<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 _WIN32
#include <dlfcn.h>
#endif

#include <pdal/plang/Environment.hpp>
#include <pdal/plang/Redirector.hpp>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL PDAL_ARRAY_API
#include <numpy/arrayobject.h>

#include <sstream>
#include <mutex>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#endif

#include <Python.h>
#include <pystate.h>
#undef toupper
#undef tolower
#undef isspace

// See ticket #1010.  This function runs when libplang is loaded.  It makes
// sure python symbols can be found by extention module .so's since on some
// platforms (notably Ubuntu), they aren't linked with libpython even though
// they depend on it.  If a platform doesn't support
// __attribute__ ((constructor)) this does nothing.  We'll have to deal with
// those as they come up.
#ifndef _WIN32
__attribute__ ((constructor))
void loadPython()
{
    ::dlopen(PDAL_PYTHON_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
}
#endif

// http://www.linuxjournal.com/article/3641
// http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I
// http://stackoverflow.com/questions/6596016/python-threads-in-c

namespace pdal
{
namespace plang
{

static Environment* g_environment=0;

EnvironmentPtr Environment::get()
{
    static std::once_flag flag;

    auto init = []()
    {
        g_environment = new Environment();
    };

    std::call_once(flag, init);

    return g_environment;
}

Environment::Environment()
{
    // This awfulness is due to the import_array MACRO that returns a value
    // in some cases and returns nothing at other times.  Defining
    // NUMPY_IMPORT_ARRAY_RETVAL to nothing makes it so we don't ever return
    // a value.  The function needs to be stuck in a function to deal with
    // the return.
    auto initNumpy = []()
    {
#undef NUMPY_IMPORT_ARRAY_RETVAL
#define NUMPY_IMPORT_ARRAY_RETVAL
        import_array();
    };

    PyImport_AppendInittab(const_cast<char*>("redirector"), redirector_init);

    Py_Initialize();
    initNumpy();
    PyImport_ImportModule("redirector");
}

Environment::~Environment()
{
    Py_Finalize();
}

void Environment::set_stdout(std::ostream* ostr)
{
    m_redirector.set_stdout(ostr);
}

void Environment::reset_stdout()
{
    m_redirector.reset_stdout();
}

std::string getTraceback()
{
    // get exception info
    PyObject *type, *value, *traceback;
    PyErr_Fetch(&type, &value, &traceback);
    PyErr_NormalizeException(&type, &value, &traceback);

    std::ostringstream mssg;
    if (traceback)
    {
        PyObject* tracebackModule;
        PyObject* tracebackDictionary;
        PyObject* tracebackFunction;

        tracebackModule = PyImport_ImportModule("traceback");
        if (!tracebackModule)
            throw pdal::pdal_error("Unable to load traceback module.");

        tracebackDictionary = PyModule_GetDict(tracebackModule);
        if (!tracebackDictionary)
            throw pdal::pdal_error("Unable to load traceback dictionary.");
        tracebackFunction =
            PyDict_GetItemString(tracebackDictionary, "format_exception");
        if (!tracebackFunction)
            throw pdal::pdal_error("Unable to find traceback function.");

        if (!PyCallable_Check(tracebackFunction))
            throw pdal::pdal_error("Invalid traceback function.");

        // create an argument for "format exception"
        PyObject* args = PyTuple_New(3);
        PyTuple_SetItem(args, 0, type);
        PyTuple_SetItem(args, 1, value);
        PyTuple_SetItem(args, 2, traceback);

        // get a list of string describing what went wrong
        PyObject* output = PyObject_CallObject(tracebackFunction, args);

        // print error message
        int n = PyList_Size(output);

        for (int i = 0; i < n; i++)
        {
            PyObject* l = PyList_GetItem(output, i);
            if (!l)
                throw pdal::pdal_error("unable to get list item in getTraceback");
            PyObject* r = PyObject_Repr(l);
            if (!r)
                throw pdal::pdal_error("unable to get repr in getTraceback");
            Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
            mssg << d;
        }

        // clean up
        Py_XDECREF(args);
        Py_XDECREF(output);
    }
    else if (value != NULL)
    {
        PyObject* r = PyObject_Repr(value);
        if (!r)
            throw pdal::pdal_error("couldn't make string representation of traceback value");
        Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
        mssg << d;
    }
    else
        mssg << "unknown error that we are unable to get a traceback for."
            "Was it already printed/taken?";

    Py_XDECREF(value);
    Py_XDECREF(type);
    Py_XDECREF(traceback);

    return mssg.str();
}

PyObject *fromMetadata(MetadataNode m)
{
    std::string name = m.name();
    std::string value = m.value();
    std::string type = m.type();
    std::string description = m.description();

    MetadataNodeList children = m.children();
    PyObject *submeta = NULL;
    if (children.size())
    {
        submeta = PyList_New(0);
        for (MetadataNode& child : children)
            PyList_Append(submeta, fromMetadata(child));
    }
    PyObject *data = PyTuple_New(5);
    PyTuple_SetItem(data, 0, PyUnicode_FromString(name.data()));
    PyTuple_SetItem(data, 1, PyUnicode_FromString(value.data()));
    PyTuple_SetItem(data, 2, PyUnicode_FromString(type.data()));
    PyTuple_SetItem(data, 3, PyUnicode_FromString(description.data()));
    PyTuple_SetItem(data, 4, submeta);

    return data;
}

std::string readPythonString(PyObject* list, Py_ssize_t index)
{
    std::stringstream ss;

    PyObject* o = PyTuple_GetItem(list, index);
    if (!o)
    {
        std::stringstream oss;
        oss << "Unable to get list item number " << index << " for list of length " << PyTuple_Size(list);
        throw pdal_error(oss.str());
    }
    PyObject* r = PyObject_Repr(o);
    if (!r)
        throw pdal::pdal_error("unable to get repr in readPythonString");
    Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
    ss << d;

    return ss.str();
}
void addMetadata(PyObject *list, MetadataNode m)
{

    if (!PyList_Check(list))
        return;

    for (Py_ssize_t i = 0; i < PyList_Size(list); ++i)
    {
        PyObject *tuple = PyList_GetItem(list, i);
        if (!PyTuple_Check(tuple) || PyTuple_Size(tuple) != 5)
            continue;

        std::string name = readPythonString(tuple, 0);
        std::string value = readPythonString(tuple, 1);

        std::string type = readPythonString(tuple, 2);
        if (type.empty())
            type = Metadata::inferType(value);

        std::string description = readPythonString(tuple, 3);

        PyObject *submeta = PyTuple_GetItem(tuple, 4);
        MetadataNode child =  m.addWithType(name, value, type, description);
        if (submeta)
            addMetadata(submeta, child);
    }
}

int Environment::getPythonDataType(Dimension::Type::Enum t)
{
    using namespace Dimension;

    switch (t)
    {
    case Type::Float:
        return NPY_FLOAT;
    case Type::Double:
        return NPY_DOUBLE;
    case Type::Signed8:
        return NPY_BYTE;
    case Type::Signed16:
        return NPY_SHORT;
    case Type::Signed32:
        return NPY_INT;
    case Type::Signed64:
        return NPY_LONGLONG;
    case Type::Unsigned8:
        return NPY_UBYTE;
    case Type::Unsigned16:
        return NPY_USHORT;
    case Type::Unsigned32:
        return NPY_UINT;
    case Type::Unsigned64:
        return NPY_ULONGLONG;
    default:
        return -1;
    }
    assert(0);

    return -1;
}

} // namespace plang
} // namespace pdal

<commit_msg>Debug for testing.<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 _WIN32
#include <dlfcn.h>
#endif

#include <pdal/plang/Environment.hpp>
#include <pdal/plang/Redirector.hpp>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL PDAL_ARRAY_API
#include <numpy/arrayobject.h>

#include <sstream>
#include <mutex>

#ifdef PDAL_COMPILER_MSVC
#  pragma warning(disable: 4127)  // conditional expression is constant
#endif

#include <Python.h>
#include <pystate.h>
#undef toupper
#undef tolower
#undef isspace

// See ticket #1010.  This function runs when libplang is loaded.  It makes
// sure python symbols can be found by extention module .so's since on some
// platforms (notably Ubuntu), they aren't linked with libpython even though
// they depend on it.  If a platform doesn't support
// __attribute__ ((constructor)) this does nothing.  We'll have to deal with
// those as they come up.
#ifndef _WIN32
__attribute__ ((constructor))
static void loadPython()
{
    std::cerr << "Force load python.\n";
    ::dlopen(PDAL_PYTHON_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
}
#endif

// http://www.linuxjournal.com/article/3641
// http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I
// http://stackoverflow.com/questions/6596016/python-threads-in-c

namespace pdal
{
namespace plang
{

static Environment* g_environment=0;

EnvironmentPtr Environment::get()
{
    static std::once_flag flag;

    auto init = []()
    {
        g_environment = new Environment();
    };

    std::call_once(flag, init);

    return g_environment;
}

Environment::Environment()
{
    // This awfulness is due to the import_array MACRO that returns a value
    // in some cases and returns nothing at other times.  Defining
    // NUMPY_IMPORT_ARRAY_RETVAL to nothing makes it so we don't ever return
    // a value.  The function needs to be stuck in a function to deal with
    // the return.
    auto initNumpy = []()
    {
#undef NUMPY_IMPORT_ARRAY_RETVAL
#define NUMPY_IMPORT_ARRAY_RETVAL
        import_array();
    };

    PyImport_AppendInittab(const_cast<char*>("redirector"), redirector_init);

    Py_Initialize();
    initNumpy();
    PyImport_ImportModule("redirector");
}

Environment::~Environment()
{
    Py_Finalize();
}

void Environment::set_stdout(std::ostream* ostr)
{
    m_redirector.set_stdout(ostr);
}

void Environment::reset_stdout()
{
    m_redirector.reset_stdout();
}

std::string getTraceback()
{
    // get exception info
    PyObject *type, *value, *traceback;
    PyErr_Fetch(&type, &value, &traceback);
    PyErr_NormalizeException(&type, &value, &traceback);

    std::ostringstream mssg;
    if (traceback)
    {
        PyObject* tracebackModule;
        PyObject* tracebackDictionary;
        PyObject* tracebackFunction;

        tracebackModule = PyImport_ImportModule("traceback");
        if (!tracebackModule)
            throw pdal::pdal_error("Unable to load traceback module.");

        tracebackDictionary = PyModule_GetDict(tracebackModule);
        if (!tracebackDictionary)
            throw pdal::pdal_error("Unable to load traceback dictionary.");
        tracebackFunction =
            PyDict_GetItemString(tracebackDictionary, "format_exception");
        if (!tracebackFunction)
            throw pdal::pdal_error("Unable to find traceback function.");

        if (!PyCallable_Check(tracebackFunction))
            throw pdal::pdal_error("Invalid traceback function.");

        // create an argument for "format exception"
        PyObject* args = PyTuple_New(3);
        PyTuple_SetItem(args, 0, type);
        PyTuple_SetItem(args, 1, value);
        PyTuple_SetItem(args, 2, traceback);

        // get a list of string describing what went wrong
        PyObject* output = PyObject_CallObject(tracebackFunction, args);

        // print error message
        int n = PyList_Size(output);

        for (int i = 0; i < n; i++)
        {
            PyObject* l = PyList_GetItem(output, i);
            if (!l)
                throw pdal::pdal_error("unable to get list item in getTraceback");
            PyObject* r = PyObject_Repr(l);
            if (!r)
                throw pdal::pdal_error("unable to get repr in getTraceback");
            Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
            mssg << d;
        }

        // clean up
        Py_XDECREF(args);
        Py_XDECREF(output);
    }
    else if (value != NULL)
    {
        PyObject* r = PyObject_Repr(value);
        if (!r)
            throw pdal::pdal_error("couldn't make string representation of traceback value");
        Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
        mssg << d;
    }
    else
        mssg << "unknown error that we are unable to get a traceback for."
            "Was it already printed/taken?";

    Py_XDECREF(value);
    Py_XDECREF(type);
    Py_XDECREF(traceback);

    return mssg.str();
}

PyObject *fromMetadata(MetadataNode m)
{
    std::string name = m.name();
    std::string value = m.value();
    std::string type = m.type();
    std::string description = m.description();

    MetadataNodeList children = m.children();
    PyObject *submeta = NULL;
    if (children.size())
    {
        submeta = PyList_New(0);
        for (MetadataNode& child : children)
            PyList_Append(submeta, fromMetadata(child));
    }
    PyObject *data = PyTuple_New(5);
    PyTuple_SetItem(data, 0, PyUnicode_FromString(name.data()));
    PyTuple_SetItem(data, 1, PyUnicode_FromString(value.data()));
    PyTuple_SetItem(data, 2, PyUnicode_FromString(type.data()));
    PyTuple_SetItem(data, 3, PyUnicode_FromString(description.data()));
    PyTuple_SetItem(data, 4, submeta);

    return data;
}

std::string readPythonString(PyObject* list, Py_ssize_t index)
{
    std::stringstream ss;

    PyObject* o = PyTuple_GetItem(list, index);
    if (!o)
    {
        std::stringstream oss;
        oss << "Unable to get list item number " << index << " for list of length " << PyTuple_Size(list);
        throw pdal_error(oss.str());
    }
    PyObject* r = PyObject_Repr(o);
    if (!r)
        throw pdal::pdal_error("unable to get repr in readPythonString");
    Py_ssize_t size;
#if PY_MAJOR_VERSION >= 3
            char* d = PyUnicode_AsUTF8AndSize(r, &size);
#else
            char* d = PyString_AsString(r);
#endif
    ss << d;

    return ss.str();
}
void addMetadata(PyObject *list, MetadataNode m)
{

    if (!PyList_Check(list))
        return;

    for (Py_ssize_t i = 0; i < PyList_Size(list); ++i)
    {
        PyObject *tuple = PyList_GetItem(list, i);
        if (!PyTuple_Check(tuple) || PyTuple_Size(tuple) != 5)
            continue;

        std::string name = readPythonString(tuple, 0);
        std::string value = readPythonString(tuple, 1);

        std::string type = readPythonString(tuple, 2);
        if (type.empty())
            type = Metadata::inferType(value);

        std::string description = readPythonString(tuple, 3);

        PyObject *submeta = PyTuple_GetItem(tuple, 4);
        MetadataNode child =  m.addWithType(name, value, type, description);
        if (submeta)
            addMetadata(submeta, child);
    }
}

int Environment::getPythonDataType(Dimension::Type::Enum t)
{
    using namespace Dimension;

    switch (t)
    {
    case Type::Float:
        return NPY_FLOAT;
    case Type::Double:
        return NPY_DOUBLE;
    case Type::Signed8:
        return NPY_BYTE;
    case Type::Signed16:
        return NPY_SHORT;
    case Type::Signed32:
        return NPY_INT;
    case Type::Signed64:
        return NPY_LONGLONG;
    case Type::Unsigned8:
        return NPY_UBYTE;
    case Type::Unsigned16:
        return NPY_USHORT;
    case Type::Unsigned32:
        return NPY_UINT;
    case Type::Unsigned64:
        return NPY_ULONGLONG;
    default:
        return -1;
    }
    assert(0);

    return -1;
}

} // namespace plang
} // namespace pdal

<|endoftext|>


<commit_before>/*************************************************************************************
    garlic-player: SMIL Player for Digital Signage
    Copyright (C) 2016 Nikolaos Saghiadinos <ns@smil-control.com>
    This file is part of the garlic-player source code

    This program is free software: you can redistribute it and/or  modify
    it under the terms of the GNU Affero General Public License, version 3,
    as published by the Free Software Foundation.

    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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************************/
#include <QQmlApplicationEngine>

#include "tools/logger.h"
#include "tools/resource_monitor.h"
#include "../player-common/cmdparser.h"
#include "../player-common/screen.h"

#if defined  Q_OS_ANDROID
    #include "Java2Cpp.h"
    #include <QtWebView>
#else
    #include <qtwebengineglobal.h>
#endif

#include "mainwindow.h"

void handleMessages(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Logger& MyLogger = Logger::getInstance();
    MyLogger.dispatchMessages(type, context, msg);
}

int main(int argc, char *argv[])
{

#if QT_VERSION < 0x059300
        qputenv("QML_DISABLE_DISK_CACHE", "true"); // due to https://bugreports.qt.io/browse/QTBUG-56935
#endif

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Raspberry and POT needs this http://thebugfreeblog.blogspot.de/2018/01/pot-570-with-qt-5100-built-for-armv8.html
    QApplication app(argc, argv);

#if defined Q_OS_ANDROID
    QtWebView::initialize();
    QtAndroid::androidActivity().callMethod<void>("registerBroadcastReceiver");
    setGlobalLibFaceForJava(MyLibFacade);
#endif
    qmlRegisterType<LibFacade>("com.garlic.LibFacade", 1, 0, "LibFacade");
    qmlRegisterType<ResourceMonitor>("com.garlic.ResourceMonitor", 1, 0, "ResourceMonitor");
    LibFacade      *MyLibFacade     = new LibFacade();
    QApplication::setApplicationName(MyLibFacade->getConfiguration()->getAppName());
    QApplication::setApplicationVersion(MyLibFacade->getConfiguration()->getVersion());
    QApplication::setApplicationDisplayName(MyLibFacade->getConfiguration()->getAppName());

    QDir dir(".");
    MyLibFacade->getConfiguration()->determineBasePath(dir.absolutePath()); // When run in terminal absolute path returns user homedirectory in QtCreator
    MyLibFacade->getConfiguration()->createDirectories();

    qInstallMessageHandler(handleMessages);

    TCmdParser MyParser(MyLibFacade);
    MyParser.addOptions();

   if (!MyParser.parse(&app))
        return 1;

    QLoggingCategory::setFilterRules("*.debug=true\nqt.*=false");

    TScreen    MyScreen(Q_NULLPTR);
    MainWindow w(&MyScreen, MyLibFacade);

    QQmlEngine::setObjectOwnership(&w, QQmlEngine::CppOwnership);

    if (MyLibFacade->getConfiguration()->getIndexUri() == "" && w.openConfigDialog() == QDialog::Rejected)
        return 0;

    w.init();

#if defined  Q_OS_ANDROID

    // preserve android screensaver https://stackoverflow.com/questions/44100627/how-to-disable-screensaver-on-qt-android-app
    // https://forum.qt.io/topic/57625/solved-keep-android-5-screen-on

    QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
    if (activity.isValid())
    {
        QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
        if (window.isValid())
        {
            const int FLAG_KEEP_SCREEN_ON = 128;
            window.callMethod<void>("addFlags", "(I)V", FLAG_KEEP_SCREEN_ON);
        }
    }
    // not to crash in Android > 5.x Clear any possible pending exceptions.
    QAndroidJniEnvironment env;
    if (env->ExceptionCheck()) {
        env->ExceptionClear();
    }

    w.showFullScreen();
#else

    w.show();

    QString val = MyParser.getWindowMode();
    if (val == "fullscreen")
        w.resizeAsNormalFullScreen();
    else if (val == "bigscreen")
        w.resizeAsBigFullScreen();
    else if (val == "windowed")
    {
        w.setMainWindowSize(MyParser.getWindowSize());
        w.resizeAsWindow();
    }
#endif
    return app.exec();
}
<commit_msg>Fix Bug fr Android<commit_after>/*************************************************************************************
    garlic-player: SMIL Player for Digital Signage
    Copyright (C) 2016 Nikolaos Saghiadinos <ns@smil-control.com>
    This file is part of the garlic-player source code

    This program is free software: you can redistribute it and/or  modify
    it under the terms of the GNU Affero General Public License, version 3,
    as published by the Free Software Foundation.

    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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*************************************************************************************/
#include <QQmlApplicationEngine>

#include "tools/logger.h"
#include "tools/resource_monitor.h"
#include "../player-common/cmdparser.h"
#include "../player-common/screen.h"

#if defined  Q_OS_ANDROID
    #include "Java2Cpp.h"
    #include <QtWebView>
#else
    #include <qtwebengineglobal.h>
#endif

#include "mainwindow.h"

void handleMessages(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Logger& MyLogger = Logger::getInstance();
    MyLogger.dispatchMessages(type, context, msg);
}

int main(int argc, char *argv[])
{

#if QT_VERSION < 0x059300
        qputenv("QML_DISABLE_DISK_CACHE", "true"); // due to https://bugreports.qt.io/browse/QTBUG-56935
#endif

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Raspberry and POT needs this http://thebugfreeblog.blogspot.de/2018/01/pot-570-with-qt-5100-built-for-armv8.html
    QApplication app(argc, argv);

    LibFacade      *MyLibFacade     = new LibFacade();
#if defined Q_OS_ANDROID
    QtWebView::initialize();
    QtAndroid::androidActivity().callMethod<void>("registerBroadcastReceiver");
    setGlobalLibFaceForJava(MyLibFacade);
#endif
    qmlRegisterType<LibFacade>("com.garlic.LibFacade", 1, 0, "LibFacade");
    qmlRegisterType<ResourceMonitor>("com.garlic.ResourceMonitor", 1, 0, "ResourceMonitor");
    QApplication::setApplicationName(MyLibFacade->getConfiguration()->getAppName());
    QApplication::setApplicationVersion(MyLibFacade->getConfiguration()->getVersion());
    QApplication::setApplicationDisplayName(MyLibFacade->getConfiguration()->getAppName());

    QDir dir(".");
    MyLibFacade->getConfiguration()->determineBasePath(dir.absolutePath()); // When run in terminal absolute path returns user homedirectory in QtCreator
    MyLibFacade->getConfiguration()->createDirectories();

    qInstallMessageHandler(handleMessages);

    TCmdParser MyParser(MyLibFacade);
    MyParser.addOptions();

   if (!MyParser.parse(&app))
        return 1;

    QLoggingCategory::setFilterRules("*.debug=true\nqt.*=false");

    TScreen    MyScreen(Q_NULLPTR);
    MainWindow w(&MyScreen, MyLibFacade);

    QQmlEngine::setObjectOwnership(&w, QQmlEngine::CppOwnership);

    if (MyLibFacade->getConfiguration()->getIndexUri() == "" && w.openConfigDialog() == QDialog::Rejected)
        return 0;

    w.init();

#if defined  Q_OS_ANDROID

    // preserve android screensaver https://stackoverflow.com/questions/44100627/how-to-disable-screensaver-on-qt-android-app
    // https://forum.qt.io/topic/57625/solved-keep-android-5-screen-on

    QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
    if (activity.isValid())
    {
        QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
        if (window.isValid())
        {
            const int FLAG_KEEP_SCREEN_ON = 128;
            window.callMethod<void>("addFlags", "(I)V", FLAG_KEEP_SCREEN_ON);
        }
    }
    // not to crash in Android > 5.x Clear any possible pending exceptions.
    QAndroidJniEnvironment env;
    if (env->ExceptionCheck()) {
        env->ExceptionClear();
    }

    w.showFullScreen();
#else

    w.show();

    QString val = MyParser.getWindowMode();
    if (val == "fullscreen")
        w.resizeAsNormalFullScreen();
    else if (val == "bigscreen")
        w.resizeAsBigFullScreen();
    else if (val == "windowed")
    {
        w.setMainWindowSize(MyParser.getWindowSize());
        w.resizeAsWindow();
    }
#endif
    return app.exec();
}
<|endoftext|>


<commit_before>/* <x0/mod_accesslog.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <cstring>
#include <cerrno>

/**
 * \ingroup plugins
 * \brief implements an accesslog log facility - in spirit of "combined" mode of apache's accesslog logs.
 */
class accesslog_plugin :
	public x0::plugin
{
private:
	struct logstream
	{
		std::string filename_;
		int fd_;

		explicit logstream(const std::string& filename)
		{
			filename_ = filename;
			fd_ = ::open(filename.c_str(), O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
		}

		~logstream()
		{
			if (fd_)
				::close(fd_);
		}

		void write(const std::string message)
		{
			if (fd_ < 0)
				return;

			if (::write(fd_, message.c_str(), message.size()) < 0)
				DEBUG("Couldn't write accesslog(%s): %s", filename_.c_str(), strerror(errno));
		}
	};

	struct context
	{
		logstream *stream;

		context() : stream(0) {}
		context(const context& v) : stream(v.stream) {}
		~context() {}
	};

	logstream *getlogstream(const std::string& filename)
	{
		auto i = streams_.find(filename);

		if (i != streams_.end())
			return i->second.get();

		return (streams_[filename] = std::shared_ptr<logstream>(new logstream(filename))).get();
	}

	logstream *getlogstream(x0::request *in)
	{
		if (context *ctx = server_.context<context>(this, in->hostid()))
			return ctx->stream;

		return 0;
	}

private:
	x0::server::request_post_hook::connection c;
	std::map<std::string, std::shared_ptr<logstream>> streams_;

public:
	accesslog_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name),
		streams_()
	{
		c = srv.request_done.connect(boost::bind(&accesslog_plugin::request_done, this, _1, _2));
	}

	~accesslog_plugin()
	{
		server_.request_done.disconnect(c);
	}

	virtual void configure()
	{
		std::string default_filename;
		bool has_global = server_.config().load("AccessLog", default_filename);

		auto hosts = server_.config()["Hosts"].keys<std::string>();
		for (auto i = hosts.begin(), e = hosts.end(); i != e; ++i)
		{
			std::string hostid(*i);
			context *ctx = server_.create_context<context>(this, hostid);

			std::string filename;
			if (server_.config()["Hosts"][hostid]["AccessLog"].load(filename))
			{
				ctx->stream = getlogstream(filename);
			}
			else if (has_global)
			{
				ctx->stream = getlogstream(default_filename);
			}
		}
	}

private:
	void request_done(x0::request *in, x0::response *out)
	{
		if (auto stream = getlogstream(in))
		{
			std::stringstream sstr;
			sstr << hostname(in);
			sstr << " - "; // identity as of identd
			sstr << username(in) << ' ';
			sstr << server_.now().htlog_str() << " \"";
			sstr << request_line(in) << "\" ";
			sstr << out->status << ' ';
			sstr << out->headers["Content-Length"] << ' ';
			sstr << '"' << getheader(in, "Referer") << "\" ";
			sstr << '"' << getheader(in, "User-Agent") << '"';
			sstr << std::endl;

			stream->write(sstr.str());
		}
	}

	inline std::string hostname(x0::request *in)
	{
		std::string name = in->connection.remote_ip();
		return !name.empty() ? name : "-";
	}

	inline std::string username(x0::request *in)
	{
		return !in->username.empty() ? in->username.str() : "-";
	}

	inline std::string request_line(x0::request *in)
	{
		std::stringstream str;

		str << in->method.str() << ' ' << in->uri.str()
			<< " HTTP/" << in->http_version_major << '.' << in->http_version_minor;

		return str.str();
	}

	inline std::string getheader(const x0::request *in, const std::string& name)
	{
		x0::buffer_ref value(in->header(name));
		return !value.empty() ? value.str() : "-";
	}
};

X0_EXPORT_PLUGIN(accesslog);
<commit_msg>accesslog: fix timestamp logging<commit_after>/* <x0/mod_accesslog.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/server.hpp>
#include <x0/request.hpp>
#include <x0/response.hpp>
#include <x0/header.hpp>
#include <x0/strutils.hpp>
#include <x0/types.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <cstring>
#include <cerrno>

/**
 * \ingroup plugins
 * \brief implements an accesslog log facility - in spirit of "combined" mode of apache's accesslog logs.
 */
class accesslog_plugin :
	public x0::plugin
{
private:
	struct logstream
	{
		std::string filename_;
		int fd_;

		explicit logstream(const std::string& filename)
		{
			filename_ = filename;
			fd_ = ::open(filename.c_str(), O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
		}

		~logstream()
		{
			if (fd_)
				::close(fd_);
		}

		void write(const std::string message)
		{
			if (fd_ < 0)
				return;

			if (::write(fd_, message.c_str(), message.size()) < 0)
				DEBUG("Couldn't write accesslog(%s): %s", filename_.c_str(), strerror(errno));
		}
	};

	struct context
	{
		logstream *stream;

		context() : stream(0) {}
		context(const context& v) : stream(v.stream) {}
		~context() {}
	};

	logstream *getlogstream(const std::string& filename)
	{
		auto i = streams_.find(filename);

		if (i != streams_.end())
			return i->second.get();

		return (streams_[filename] = std::shared_ptr<logstream>(new logstream(filename))).get();
	}

	logstream *getlogstream(x0::request *in)
	{
		if (context *ctx = server_.context<context>(this, in->hostid()))
			return ctx->stream;

		return 0;
	}

private:
	x0::server::request_post_hook::connection c;
	std::map<std::string, std::shared_ptr<logstream>> streams_;

public:
	accesslog_plugin(x0::server& srv, const std::string& name) :
		x0::plugin(srv, name),
		streams_()
	{
		c = srv.request_done.connect(boost::bind(&accesslog_plugin::request_done, this, _1, _2));
	}

	~accesslog_plugin()
	{
		server_.request_done.disconnect(c);
	}

	virtual void configure()
	{
		std::string default_filename;
		bool has_global = server_.config().load("AccessLog", default_filename);

		auto hosts = server_.config()["Hosts"].keys<std::string>();
		for (auto i = hosts.begin(), e = hosts.end(); i != e; ++i)
		{
			std::string hostid(*i);
			context *ctx = server_.create_context<context>(this, hostid);

			std::string filename;
			if (server_.config()["Hosts"][hostid]["AccessLog"].load(filename))
			{
				ctx->stream = getlogstream(filename);
			}
			else if (has_global)
			{
				ctx->stream = getlogstream(default_filename);
			}
		}
	}

private:
	void request_done(x0::request *in, x0::response *out)
	{
		if (auto stream = getlogstream(in))
		{
			std::stringstream sstr;
			sstr << hostname(in);
			sstr << " - "; // identity as of identd
			sstr << username(in) << ' ';
			sstr << server_.now().htlog_str().c_str() << " \"";
			sstr << request_line(in) << "\" ";
			sstr << out->status << ' ';
			sstr << out->headers["Content-Length"] << ' ';
			sstr << '"' << getheader(in, "Referer") << "\" ";
			sstr << '"' << getheader(in, "User-Agent") << '"';
			sstr << std::endl;

			stream->write(sstr.str());
		}
	}

	inline std::string hostname(x0::request *in)
	{
		std::string name = in->connection.remote_ip();
		return !name.empty() ? name : "-";
	}

	inline std::string username(x0::request *in)
	{
		return !in->username.empty() ? in->username.str() : "-";
	}

	inline std::string request_line(x0::request *in)
	{
		std::stringstream str;

		str << in->method.str() << ' ' << in->uri.str()
			<< " HTTP/" << in->http_version_major << '.' << in->http_version_minor;

		return str.str();
	}

	inline std::string getheader(const x0::request *in, const std::string& name)
	{
		x0::buffer_ref value(in->header(name));
		return !value.empty() ? value.str() : "-";
	}
};

X0_EXPORT_PLUGIN(accesslog);
<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2019 LibRaw LLC (info@libraw.org)
    Copyright (C) 2020 Roman Lebedev

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decompressors/PanasonicDecompressorV6.h" // for PanasonicDecompre...
#include "common/Point.h"                          // for iPoint2D
#include "common/RawImage.h"                       // for RawImage, RawImag...
#include "decoders/RawDecoderException.h"          // for ThrowRDE
#include <algorithm>                               // for copy_n
#include <cstdint>                                 // for uint16_t, uint32_t
#include <cstdlib>                                 // for free, malloc

namespace rawspeed {

namespace {
struct pana_cs6_page_decoder {
  unsigned int pixelbuffer[14], lastoffset, maxoffset;
  unsigned char current;
  const unsigned char* buffer;
  pana_cs6_page_decoder(const unsigned char* _buffer, unsigned int bsize)
      : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) {}
  void read_page(); // will throw IO error if not enough space in buffer
  unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; }
};

void pana_cs6_page_decoder::read_page() {
  if (!buffer || (maxoffset - lastoffset < 16))
    ThrowRDE("Input failure");
#define wbuffer(i) ((unsigned short)buffer[lastoffset + 15 - i])
  pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit
  pixelbuffer[1] =
      (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) &
      0x3fff;
  pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3;
  pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4);
  pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6);
  pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4);
  pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3;
  pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8);
  pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6);
  pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff;
  pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3;
  pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12);
  pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff;
  pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff;
#undef wbuffer
  current = 0;
  lastoffset += 16;
}
} // namespace

PanasonicDecompressorV6::PanasonicDecompressorV6(const RawImage& img,
                                                 ByteStream input_,
                                                 uint32_t bps_)
    : mRaw(img), input(std::move(input_)) {
  if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
      mRaw->getBpp() != sizeof(uint16_t))
    ThrowRDE("Unexpected component count / data type");

  if (!mRaw->dim.hasPositiveArea()) {
    ThrowRDE("Unexpected image dimensions found: (%i; %i)", mRaw->dim.x,
             mRaw->dim.y);
  }
}

void PanasonicDecompressorV6::decompress() {
  const int rowstep = 16;
  const int blocksperrow = mRaw->dim.x / 11;
  const int rowbytes = blocksperrow * 16;

  for (int row = 0; row < mRaw->dim.y - rowstep + 1; row += rowstep) {
    int rowstoread = std::min(rowstep, mRaw->dim.y - row);
    pana_cs6_page_decoder page(input.getData(rowbytes * rowstep),
                               rowbytes * rowstoread);
    for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) {
      auto* rowptr =
          reinterpret_cast<uint16_t*>(mRaw->getDataUncropped(0, row + crow));
      for (int rblock = 0; rblock < blocksperrow; rblock++) {
        page.read_page();
        unsigned oddeven[2] = {0, 0};
        unsigned nonzero[2] = {0, 0};
        unsigned pmul = 0;
        unsigned pixel_base = 0;
        for (int pix = 0; pix < 11; pix++) {
          if (pix % 3 == 2) {
            unsigned base = page.nextpixel();
            if (base > 3)
              ThrowRDE("Invariant failure");
            if (base == 3)
              base = 4;
            pixel_base = 0x200 << base;
            pmul = 1 << base;
          }
          unsigned epixel = page.nextpixel();
          if (oddeven[pix % 2]) {
            epixel *= pmul;
            if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base)
              epixel += nonzero[pix % 2] - pixel_base;
            nonzero[pix % 2] = epixel;
          } else {
            oddeven[pix % 2] = epixel;
            if (epixel)
              nonzero[pix % 2] = epixel;
            else
              epixel = nonzero[pix % 2];
          }
          auto spix = static_cast<unsigned>(static_cast<int>(epixel) - 0xf);
          if (spix <= 0xffff)
            rowptr[col++] = spix & 0xffff;
          else {
            epixel = static_cast<signed int>(epixel + 0x7ffffff1) >> 0x1f;
            rowptr[col++] = epixel & 0x3fff;
          }
        }
      }
    }
  }
}

} // namespace rawspeed
<commit_msg>PanasonicDecompressorV6: clang-tidy: avoid using macro where lambda would work<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2019 LibRaw LLC (info@libraw.org)
    Copyright (C) 2020 Roman Lebedev

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "decompressors/PanasonicDecompressorV6.h" // for PanasonicDecompre...
#include "common/Point.h"                          // for iPoint2D
#include "common/RawImage.h"                       // for RawImage, RawImag...
#include "decoders/RawDecoderException.h"          // for ThrowRDE
#include <algorithm>                               // for copy_n
#include <cstdint>                                 // for uint16_t, uint32_t
#include <cstdlib>                                 // for free, malloc

namespace rawspeed {

namespace {
struct pana_cs6_page_decoder {
  unsigned int pixelbuffer[14], lastoffset, maxoffset;
  unsigned char current;
  const unsigned char* buffer;
  pana_cs6_page_decoder(const unsigned char* _buffer, unsigned int bsize)
      : lastoffset(0), maxoffset(bsize), current(0), buffer(_buffer) {}
  void read_page(); // will throw IO error if not enough space in buffer
  unsigned int nextpixel() { return current < 14 ? pixelbuffer[current++] : 0; }
};

void pana_cs6_page_decoder::read_page() {
  if (!buffer || (maxoffset - lastoffset < 16))
    ThrowRDE("Input failure");
  auto wbuffer = [&](int i) {
    return (unsigned short)buffer[lastoffset + 15 - i];
  };
  pixelbuffer[0] = (wbuffer(0) << 6) | (wbuffer(1) >> 2); // 14 bit
  pixelbuffer[1] =
      (((wbuffer(1) & 0x3) << 12) | (wbuffer(2) << 4) | (wbuffer(3) >> 4)) &
      0x3fff;
  pixelbuffer[2] = (wbuffer(3) >> 2) & 0x3;
  pixelbuffer[3] = ((wbuffer(3) & 0x3) << 8) | wbuffer(4);
  pixelbuffer[4] = (wbuffer(5) << 2) | (wbuffer(6) >> 6);
  pixelbuffer[5] = ((wbuffer(6) & 0x3f) << 4) | (wbuffer(7) >> 4);
  pixelbuffer[6] = (wbuffer(7) >> 2) & 0x3;
  pixelbuffer[7] = ((wbuffer(7) & 0x3) << 8) | wbuffer(8);
  pixelbuffer[8] = ((wbuffer(9) << 2) & 0x3fc) | (wbuffer(10) >> 6);
  pixelbuffer[9] = ((wbuffer(10) << 4) | (wbuffer(11) >> 4)) & 0x3ff;
  pixelbuffer[10] = (wbuffer(11) >> 2) & 0x3;
  pixelbuffer[11] = ((wbuffer(11) & 0x3) << 8) | wbuffer(12);
  pixelbuffer[12] = (((wbuffer(13) << 2) & 0x3fc) | wbuffer(14) >> 6) & 0x3ff;
  pixelbuffer[13] = ((wbuffer(14) << 4) | (wbuffer(15) >> 4)) & 0x3ff;
#undef wbuffer
  current = 0;
  lastoffset += 16;
}
} // namespace

PanasonicDecompressorV6::PanasonicDecompressorV6(const RawImage& img,
                                                 ByteStream input_,
                                                 uint32_t bps_)
    : mRaw(img), input(std::move(input_)) {
  if (mRaw->getCpp() != 1 || mRaw->getDataType() != TYPE_USHORT16 ||
      mRaw->getBpp() != sizeof(uint16_t))
    ThrowRDE("Unexpected component count / data type");

  if (!mRaw->dim.hasPositiveArea()) {
    ThrowRDE("Unexpected image dimensions found: (%i; %i)", mRaw->dim.x,
             mRaw->dim.y);
  }
}

void PanasonicDecompressorV6::decompress() {
  const int rowstep = 16;
  const int blocksperrow = mRaw->dim.x / 11;
  const int rowbytes = blocksperrow * 16;

  for (int row = 0; row < mRaw->dim.y - rowstep + 1; row += rowstep) {
    int rowstoread = std::min(rowstep, mRaw->dim.y - row);
    pana_cs6_page_decoder page(input.getData(rowbytes * rowstep),
                               rowbytes * rowstoread);
    for (int crow = 0, col = 0; crow < rowstoread; crow++, col = 0) {
      auto* rowptr =
          reinterpret_cast<uint16_t*>(mRaw->getDataUncropped(0, row + crow));
      for (int rblock = 0; rblock < blocksperrow; rblock++) {
        page.read_page();
        unsigned oddeven[2] = {0, 0};
        unsigned nonzero[2] = {0, 0};
        unsigned pmul = 0;
        unsigned pixel_base = 0;
        for (int pix = 0; pix < 11; pix++) {
          if (pix % 3 == 2) {
            unsigned base = page.nextpixel();
            if (base > 3)
              ThrowRDE("Invariant failure");
            if (base == 3)
              base = 4;
            pixel_base = 0x200 << base;
            pmul = 1 << base;
          }
          unsigned epixel = page.nextpixel();
          if (oddeven[pix % 2]) {
            epixel *= pmul;
            if (pixel_base < 0x2000 && nonzero[pix % 2] > pixel_base)
              epixel += nonzero[pix % 2] - pixel_base;
            nonzero[pix % 2] = epixel;
          } else {
            oddeven[pix % 2] = epixel;
            if (epixel)
              nonzero[pix % 2] = epixel;
            else
              epixel = nonzero[pix % 2];
          }
          auto spix = static_cast<unsigned>(static_cast<int>(epixel) - 0xf);
          if (spix <= 0xffff)
            rowptr[col++] = spix & 0xffff;
          else {
            epixel = static_cast<signed int>(epixel + 0x7ffffff1) >> 0x1f;
            rowptr[col++] = epixel & 0x3fff;
          }
        }
      }
    }
  }
}

} // namespace rawspeed
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.7  2001/10/21 19:04:55  hristov
Several patches were done to adapt the barel reconstruction to the multi-event case. Some memory leaks were corrected. (Yu.Belikov)

Revision 1.6  2001/08/30 09:28:48  hristov
TTree names are explicitly set via SetName(name) and then Write() is called

Revision 1.5  2001/07/20 14:32:44  kowal2
Processing of many events possible now

Revision 1.4  2001/04/17 08:06:27  hristov
Possibility to define the magnetic field in the reconstruction (Yu.Belikov)

Revision 1.3  2000/10/05 16:14:01  kowal2
Forward declarations.

Revision 1.2  2000/06/30 12:07:50  kowal2
Updated from the TPC-PreRelease branch

Revision 1.1.2.1  2000/06/25 08:53:55  kowal2
Splitted from AliTPCtracking

*/

//-------------------------------------------------------
//          Implementation of the TPC clusterer
//
//   Origin: Jouri Belikov, CERN, Jouri.Belikov@cern.ch
//-------------------------------------------------------

#include "AliTPCclusterer.h"
#include "AliTPCcluster.h"
#include <TObjArray.h>
#include <TFile.h>
#include "AliTPCClustersArray.h"
#include "AliTPCClustersRow.h"
#include "AliDigits.h"
#include "AliSimDigits.h"
#include "AliTPCParam.h"
#include <iostream.h>
#include <TTree.h>

void AliTPCclusterer::FindPeaks(Int_t k,Int_t max,
AliBin *b,Int_t *idx,UInt_t *msk,Int_t& n) {
  //find local maxima
  if (n<31)
  if (IsMaximum(k,max,b)) {
    idx[n]=k; msk[n]=(2<<n);
    n++;
  }
  b[k].SetMask(0);
  if (b[k-max].GetMask()&1) FindPeaks(k-max,max,b,idx,msk,n);
  if (b[k-1  ].GetMask()&1) FindPeaks(k-1  ,max,b,idx,msk,n);
  if (b[k+max].GetMask()&1) FindPeaks(k+max,max,b,idx,msk,n);
  if (b[k+1  ].GetMask()&1) FindPeaks(k+1  ,max,b,idx,msk,n);
}

void AliTPCclusterer::MarkPeak(Int_t k, Int_t max, AliBin *bins, UInt_t m) {
  //mark this peak
  UShort_t q=bins[k].GetQ();

  bins[k].SetMask(bins[k].GetMask()|m);

  if (bins[k-max].GetQ() <= q)
     if ((bins[k-max].GetMask()&m) == 0) MarkPeak(k-max,max,bins,m);
  if (bins[k-1  ].GetQ() <= q)
     if ((bins[k-1  ].GetMask()&m) == 0) MarkPeak(k-1  ,max,bins,m);
  if (bins[k+max].GetQ() <= q)
     if ((bins[k+max].GetMask()&m) == 0) MarkPeak(k+max,max,bins,m);
  if (bins[k+1  ].GetQ() <= q)
     if ((bins[k+1  ].GetMask()&m) == 0) MarkPeak(k+1  ,max,bins,m);
}

void AliTPCclusterer::MakeCluster(Int_t k,Int_t max,AliBin *bins,UInt_t m,
AliTPCcluster &c) {
  //make cluster using digits of this peak
  Float_t q=(Float_t)bins[k].GetQ();
  Int_t i=k/max, j=k-i*max;

  c.SetQ(c.GetQ()+q);
  c.SetY(c.GetY()+i*q);
  c.SetZ(c.GetZ()+j*q);
  c.SetSigmaY2(c.GetSigmaY2()+i*i*q);
  c.SetSigmaZ2(c.GetSigmaZ2()+j*j*q);

  bins[k].SetMask(0xFFFFFFFE);

  if (bins[k-max].GetMask() == m) MakeCluster(k-max,max,bins,m,c);
  if (bins[k-1  ].GetMask() == m) MakeCluster(k-1  ,max,bins,m,c);
  if (bins[k+max].GetMask() == m) MakeCluster(k+max,max,bins,m,c);
  if (bins[k+1  ].GetMask() == m) MakeCluster(k+1  ,max,bins,m,c);
}

//_____________________________________________________________________________
void AliTPCclusterer::Digits2Clusters(const AliTPCParam *par, TFile *of, Int_t eventn)
{
  //-----------------------------------------------------------------
  // This is a simple cluster finder.
  //-----------------------------------------------------------------
  TDirectory *savedir=gDirectory;

  if (!of->IsOpen()) {
     cerr<<"AliTPC::Digits2Clusters(): output file not open !\n";
     return;
  }

  const Int_t kMAXZ=par->GetMaxTBin()+2;

  char  dname[100];
  char   cname[100];
  if (eventn==-1) {

    // for backward compatibility

    sprintf(dname,"TreeD_75x40_100x60_150x60");
    sprintf(cname,"TreeC_TPC");
  }
  else {
    sprintf(dname,"TreeD_75x40_100x60_150x60_%d",eventn);
    sprintf(cname,"TreeC_TPC_%d",eventn);
  }
  TTree *t = (TTree *)gDirectory->Get(dname);

  AliSimDigits digarr, *dummy=&digarr;
  t->GetBranch("Segment")->SetAddress(&dummy);
  Stat_t nentries = t->GetEntries();

  of->cd();

  ((AliTPCParam*)par)->Write(par->GetTitle());
  AliTPCClustersArray carray;
  carray.Setup(par);
  carray.SetClusterType("AliTPCcluster");
  carray.MakeTree();

  Int_t nclusters=0;

  for (Int_t n=0; n<nentries; n++) {
    t->GetEvent(n);
    Int_t sec, row;
    if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) {
       cerr<<"AliTPC warning: invalid segment ID ! "<<digarr.GetID()<<endl;
       continue;
    }

    AliTPCClustersRow *clrow=carray.CreateRow(sec,row);

    Float_t rx=par->GetPadRowRadii(sec,row);

    Int_t npads, sign;
    {
       const Int_t kNIS=par->GetNInnerSector(), kNOS=par->GetNOuterSector();
       if (sec < kNIS) {
          npads = par->GetNPadsLow(row);
          sign = (sec < kNIS/2) ? 1 : -1;
       } else {
          npads = par->GetNPadsUp(row);
          sign = ((sec-kNIS) < kNOS/2) ? 1 : -1;
       }
    }

    const Int_t kMAXBIN=kMAXZ*(npads+2);
    AliBin *bins=new AliBin[kMAXBIN];
    for (Int_t ii=0;ii<kMAXBIN;ii++) {
       bins[ii].SetQ(0); bins[ii].SetMask(0xFFFFFFFE);
    }

    digarr.First();
    do {
       Short_t dig=digarr.CurrentDigit();
       if (dig<=par->GetZeroSup()) continue;
       Int_t j=digarr.CurrentRow()+1, i=digarr.CurrentColumn()+1;
       bins[i*kMAXZ+j].SetQ(dig);
       bins[i*kMAXZ+j].SetMask(1);
    } while (digarr.Next());

    Int_t ncl=0;
    for (Int_t i=0; i<kMAXBIN; i++) {
      if ((bins[i].GetMask()&1) == 0) continue;
      Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
      FindPeaks(i, kMAXZ, bins, idx, msk, npeaks);

      if (npeaks>30) continue;

      Int_t k,l;
      for (k=0; k<npeaks-1; k++){//mark adjacent peaks
        if (idx[k] < 0) continue; //this peak is already removed
        for (l=k+1; l<npeaks; l++) {
           if (idx[l] < 0) continue; //this peak is already removed
           Int_t ki=idx[k]/kMAXZ, kj=idx[k] - ki*kMAXZ;
           Int_t li=idx[l]/kMAXZ, lj=idx[l] - li*kMAXZ;
           Int_t di=TMath::Abs(ki - li);
           Int_t dj=TMath::Abs(kj - lj);
           if (di>1 || dj>1) continue;
           if (bins[idx[k]].GetQ() > bins[idx[l]].GetQ()) {
              msk[l]=msk[k];
              idx[l]*=-1;
           } else {
              msk[k]=msk[l];
              idx[k]*=-1;
              break;
           }
        }
      }

      for (k=0; k<npeaks; k++) {
        MarkPeak(TMath::Abs(idx[k]), kMAXZ, bins, msk[k]);
      }

      for (k=0; k<npeaks; k++) {
         if (idx[k] < 0) continue; //removed peak
         AliTPCcluster c;
         MakeCluster(idx[k], kMAXZ, bins, msk[k], c);
         if (c.GetQ() < 5) continue; //noise cluster
         c.SetY(c.GetY()/c.GetQ());
         c.SetZ(c.GetZ()/c.GetQ());

         Float_t s2 = c.GetSigmaY2()/c.GetQ() - c.GetY()*c.GetY();
         Float_t w=par->GetPadPitchWidth(sec);
         c.SetSigmaY2((s2 + 1./12.)*w*w);
         if (s2 != 0.) {
	   c.SetSigmaY2(c.GetSigmaY2()*0.108);
	   if (sec<par->GetNInnerSector()) c.SetSigmaY2(c.GetSigmaY2()*2.07);
         }

         s2 = c.GetSigmaZ2()/c.GetQ() - c.GetZ()*c.GetZ();
         w=par->GetZWidth();
         c.SetSigmaZ2((s2 + 1./12.)*w*w);
         if (s2 != 0.) {
	   c.SetSigmaZ2(c.GetSigmaZ2()*0.169);
	   if (sec<par->GetNInnerSector()) c.SetSigmaZ2(c.GetSigmaZ2()*1.77);
         }

         c.SetY((c.GetY() - 0.5 - 0.5*npads)*par->GetPadPitchWidth(sec));
         c.SetZ(par->GetZWidth()*(c.GetZ()-1));
         c.SetZ(c.GetZ() - 3.*par->GetZSigma()); // PASA delay
         c.SetZ(sign*(par->GetZLength() - c.GetZ()));

         if (rx<230./250.*TMath::Abs(c.GetZ())) continue;

         Int_t ki=idx[k]/kMAXZ, kj=idx[k] - ki*kMAXZ;
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,0),0);
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,1),1);
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,2),2);

         c.SetQ(bins[idx[k]].GetQ());

         if (ki==1 || ki==npads || kj==1 || kj==kMAXZ-2) {
           c.SetSigmaY2(c.GetSigmaY2()*25.);
           c.SetSigmaZ2(c.GetSigmaZ2()*4.);
         }
         clrow->InsertCluster(&c); ncl++;
      }
    }
    carray.StoreRow(sec,row);
    carray.ClearRow(sec,row);

    //cerr<<"sector, row, compressed digits, clusters: "
    //<<sec<<' '<<row<<' '<<digarr.GetSize()<<' '<<ncl<<"                  \r";

    nclusters+=ncl;

    delete[] bins;
  }

  cerr<<"Number of found clusters : "<<nclusters<<"                        \n";

  carray.GetTree()->SetName(cname);
  carray.GetTree()->Write();
  savedir->cd();

  delete t;  //Thanks to Mariana Bondila
}

<commit_msg>Protection against nonexisting input tree<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.8  2002/03/29 06:57:45  kowal2
Restored backward compatibility to use the hits from Dec. 2000 production.

Revision 1.7  2001/10/21 19:04:55  hristov
Several patches were done to adapt the barel reconstruction to the multi-event case. Some memory leaks were corrected. (Yu.Belikov)

Revision 1.6  2001/08/30 09:28:48  hristov
TTree names are explicitly set via SetName(name) and then Write() is called

Revision 1.5  2001/07/20 14:32:44  kowal2
Processing of many events possible now

Revision 1.4  2001/04/17 08:06:27  hristov
Possibility to define the magnetic field in the reconstruction (Yu.Belikov)

Revision 1.3  2000/10/05 16:14:01  kowal2
Forward declarations.

Revision 1.2  2000/06/30 12:07:50  kowal2
Updated from the TPC-PreRelease branch

Revision 1.1.2.1  2000/06/25 08:53:55  kowal2
Splitted from AliTPCtracking

*/

//-------------------------------------------------------
//          Implementation of the TPC clusterer
//
//   Origin: Jouri Belikov, CERN, Jouri.Belikov@cern.ch
//-------------------------------------------------------

#include "AliTPCclusterer.h"
#include "AliTPCcluster.h"
#include <TObjArray.h>
#include <TFile.h>
#include "AliTPCClustersArray.h"
#include "AliTPCClustersRow.h"
#include "AliDigits.h"
#include "AliSimDigits.h"
#include "AliTPCParam.h"
#include <iostream.h>
#include <TTree.h>

void AliTPCclusterer::FindPeaks(Int_t k,Int_t max,
AliBin *b,Int_t *idx,UInt_t *msk,Int_t& n) {
  //find local maxima
  if (n<31)
  if (IsMaximum(k,max,b)) {
    idx[n]=k; msk[n]=(2<<n);
    n++;
  }
  b[k].SetMask(0);
  if (b[k-max].GetMask()&1) FindPeaks(k-max,max,b,idx,msk,n);
  if (b[k-1  ].GetMask()&1) FindPeaks(k-1  ,max,b,idx,msk,n);
  if (b[k+max].GetMask()&1) FindPeaks(k+max,max,b,idx,msk,n);
  if (b[k+1  ].GetMask()&1) FindPeaks(k+1  ,max,b,idx,msk,n);
}

void AliTPCclusterer::MarkPeak(Int_t k, Int_t max, AliBin *bins, UInt_t m) {
  //mark this peak
  UShort_t q=bins[k].GetQ();

  bins[k].SetMask(bins[k].GetMask()|m);

  if (bins[k-max].GetQ() <= q)
     if ((bins[k-max].GetMask()&m) == 0) MarkPeak(k-max,max,bins,m);
  if (bins[k-1  ].GetQ() <= q)
     if ((bins[k-1  ].GetMask()&m) == 0) MarkPeak(k-1  ,max,bins,m);
  if (bins[k+max].GetQ() <= q)
     if ((bins[k+max].GetMask()&m) == 0) MarkPeak(k+max,max,bins,m);
  if (bins[k+1  ].GetQ() <= q)
     if ((bins[k+1  ].GetMask()&m) == 0) MarkPeak(k+1  ,max,bins,m);
}

void AliTPCclusterer::MakeCluster(Int_t k,Int_t max,AliBin *bins,UInt_t m,
AliTPCcluster &c) {
  //make cluster using digits of this peak
  Float_t q=(Float_t)bins[k].GetQ();
  Int_t i=k/max, j=k-i*max;

  c.SetQ(c.GetQ()+q);
  c.SetY(c.GetY()+i*q);
  c.SetZ(c.GetZ()+j*q);
  c.SetSigmaY2(c.GetSigmaY2()+i*i*q);
  c.SetSigmaZ2(c.GetSigmaZ2()+j*j*q);

  bins[k].SetMask(0xFFFFFFFE);

  if (bins[k-max].GetMask() == m) MakeCluster(k-max,max,bins,m,c);
  if (bins[k-1  ].GetMask() == m) MakeCluster(k-1  ,max,bins,m,c);
  if (bins[k+max].GetMask() == m) MakeCluster(k+max,max,bins,m,c);
  if (bins[k+1  ].GetMask() == m) MakeCluster(k+1  ,max,bins,m,c);
}

//_____________________________________________________________________________
void AliTPCclusterer::Digits2Clusters(const AliTPCParam *par, TFile *of, Int_t eventn)
{
  //-----------------------------------------------------------------
  // This is a simple cluster finder.
  //-----------------------------------------------------------------
  TDirectory *savedir=gDirectory;

  if (!of->IsOpen()) {
     cerr<<"AliTPC::Digits2Clusters(): output file not open !\n";
     return;
  }

  const Int_t kMAXZ=par->GetMaxTBin()+2;

  char  dname[100];
  char   cname[100];
  if (eventn==-1) {

    // for backward compatibility

    sprintf(dname,"TreeD_75x40_100x60_150x60");
    sprintf(cname,"TreeC_TPC");
  }
  else {
    sprintf(dname,"TreeD_75x40_100x60_150x60_%d",eventn);
    sprintf(cname,"TreeC_TPC_%d",eventn);
  }
  TTree *t = (TTree *)gDirectory->Get(dname);

  if (!t) {
    cerr<<"Input tree with "<<dname<<" not found"<<endl;
    return;
  }

  AliSimDigits digarr, *dummy=&digarr;
  t->GetBranch("Segment")->SetAddress(&dummy);
  Stat_t nentries = t->GetEntries();

  of->cd();

  ((AliTPCParam*)par)->Write(par->GetTitle());
  AliTPCClustersArray carray;
  carray.Setup(par);
  carray.SetClusterType("AliTPCcluster");
  carray.MakeTree();

  Int_t nclusters=0;

  for (Int_t n=0; n<nentries; n++) {
    t->GetEvent(n);
    Int_t sec, row;
    if (!par->AdjustSectorRow(digarr.GetID(),sec,row)) {
       cerr<<"AliTPC warning: invalid segment ID ! "<<digarr.GetID()<<endl;
       continue;
    }

    AliTPCClustersRow *clrow=carray.CreateRow(sec,row);

    Float_t rx=par->GetPadRowRadii(sec,row);

    Int_t npads, sign;
    {
       const Int_t kNIS=par->GetNInnerSector(), kNOS=par->GetNOuterSector();
       if (sec < kNIS) {
          npads = par->GetNPadsLow(row);
          sign = (sec < kNIS/2) ? 1 : -1;
       } else {
          npads = par->GetNPadsUp(row);
          sign = ((sec-kNIS) < kNOS/2) ? 1 : -1;
       }
    }

    const Int_t kMAXBIN=kMAXZ*(npads+2);
    AliBin *bins=new AliBin[kMAXBIN];
    for (Int_t ii=0;ii<kMAXBIN;ii++) {
       bins[ii].SetQ(0); bins[ii].SetMask(0xFFFFFFFE);
    }

    digarr.First();
    do {
       Short_t dig=digarr.CurrentDigit();
       if (dig<=par->GetZeroSup()) continue;
       Int_t j=digarr.CurrentRow()+1, i=digarr.CurrentColumn()+1;
       bins[i*kMAXZ+j].SetQ(dig);
       bins[i*kMAXZ+j].SetMask(1);
    } while (digarr.Next());

    Int_t ncl=0;
    for (Int_t i=0; i<kMAXBIN; i++) {
      if ((bins[i].GetMask()&1) == 0) continue;
      Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
      FindPeaks(i, kMAXZ, bins, idx, msk, npeaks);

      if (npeaks>30) continue;

      Int_t k,l;
      for (k=0; k<npeaks-1; k++){//mark adjacent peaks
        if (idx[k] < 0) continue; //this peak is already removed
        for (l=k+1; l<npeaks; l++) {
           if (idx[l] < 0) continue; //this peak is already removed
           Int_t ki=idx[k]/kMAXZ, kj=idx[k] - ki*kMAXZ;
           Int_t li=idx[l]/kMAXZ, lj=idx[l] - li*kMAXZ;
           Int_t di=TMath::Abs(ki - li);
           Int_t dj=TMath::Abs(kj - lj);
           if (di>1 || dj>1) continue;
           if (bins[idx[k]].GetQ() > bins[idx[l]].GetQ()) {
              msk[l]=msk[k];
              idx[l]*=-1;
           } else {
              msk[k]=msk[l];
              idx[k]*=-1;
              break;
           }
        }
      }

      for (k=0; k<npeaks; k++) {
        MarkPeak(TMath::Abs(idx[k]), kMAXZ, bins, msk[k]);
      }

      for (k=0; k<npeaks; k++) {
         if (idx[k] < 0) continue; //removed peak
         AliTPCcluster c;
         MakeCluster(idx[k], kMAXZ, bins, msk[k], c);
         if (c.GetQ() < 5) continue; //noise cluster
         c.SetY(c.GetY()/c.GetQ());
         c.SetZ(c.GetZ()/c.GetQ());

         Float_t s2 = c.GetSigmaY2()/c.GetQ() - c.GetY()*c.GetY();
         Float_t w=par->GetPadPitchWidth(sec);
         c.SetSigmaY2((s2 + 1./12.)*w*w);
         if (s2 != 0.) {
	   c.SetSigmaY2(c.GetSigmaY2()*0.108);
	   if (sec<par->GetNInnerSector()) c.SetSigmaY2(c.GetSigmaY2()*2.07);
         }

         s2 = c.GetSigmaZ2()/c.GetQ() - c.GetZ()*c.GetZ();
         w=par->GetZWidth();
         c.SetSigmaZ2((s2 + 1./12.)*w*w);
         if (s2 != 0.) {
	   c.SetSigmaZ2(c.GetSigmaZ2()*0.169);
	   if (sec<par->GetNInnerSector()) c.SetSigmaZ2(c.GetSigmaZ2()*1.77);
         }

         c.SetY((c.GetY() - 0.5 - 0.5*npads)*par->GetPadPitchWidth(sec));
         c.SetZ(par->GetZWidth()*(c.GetZ()-1));
         c.SetZ(c.GetZ() - 3.*par->GetZSigma()); // PASA delay
         c.SetZ(sign*(par->GetZLength() - c.GetZ()));

         if (rx<230./250.*TMath::Abs(c.GetZ())) continue;

         Int_t ki=idx[k]/kMAXZ, kj=idx[k] - ki*kMAXZ;
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,0),0);
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,1),1);
         c.SetLabel(digarr.GetTrackID(kj-1,ki-1,2),2);

         c.SetQ(bins[idx[k]].GetQ());

         if (ki==1 || ki==npads || kj==1 || kj==kMAXZ-2) {
           c.SetSigmaY2(c.GetSigmaY2()*25.);
           c.SetSigmaZ2(c.GetSigmaZ2()*4.);
         }
         clrow->InsertCluster(&c); ncl++;
      }
    }
    carray.StoreRow(sec,row);
    carray.ClearRow(sec,row);

    //cerr<<"sector, row, compressed digits, clusters: "
    //<<sec<<' '<<row<<' '<<digarr.GetSize()<<' '<<ncl<<"                  \r";

    nclusters+=ncl;

    delete[] bins;
  }

  cerr<<"Number of found clusters : "<<nclusters<<"                        \n";

  carray.GetTree()->SetName(cname);
  carray.GetTree()->Write();
  savedir->cd();

  delete t;  //Thanks to Mariana Bondila
}

<|endoftext|>


<commit_before>#include "MusicBar.h"

MusicBar::MusicBar(SongPlayer *songPlayer)
{
    mPlayer = songPlayer;
    musicbarSurfaceWidth = 1080;
    musicbarSurfaceHeight = 64;
    surface = SDL_CreateRGBSurface(0, musicbarSurfaceWidth, musicbarSurfaceHeight, 32, 0, 0, 0, 0);
    init();
}

int MusicBar::init()
{
    int songNameFontSize;
    int timeFontSize;

    songNameFontSize = 45;
    timeFontSize = 25;

    if (TTF_Init() !=0)
    {
        fprintf(stderr, "TTF_Init Failed%s\n", TTF_GetError());
        SDL_Quit();
        exit(1);
    }

    songNameFont = TTF_OpenFont("assets/ant-maru.ttf", songNameFontSize);
    if (songNameFont == NULL)
    {
        fprintf(stderr, "TTF_OpenFont Failed%s\n", TTF_GetError());
        TTF_Quit();
        SDL_Quit();
        exit(1);
    }

    timeFont = TTF_OpenFont("assets/Trebuchet-MS.ttf", timeFontSize);
    if (timeFont == NULL)
    {
        fprintf(stderr, "TTF_OpenFont Failed%s\n", TTF_GetError());
        TTF_Quit();
        SDL_Quit();
        exit(1);
    }
}

void MusicBar::drawSongName()
{
    std::string songName;
    int songStringLength;
    const char * songChar;
    int songWidth;
    int songHeight;

    songName = mPlayer->currentSong();
    songStringLength = songName.length();
    songName = songName.substr(12, songStringLength - 16); // removes SongLibrary/ and .mp3 from songName
    songChar = songName.c_str();

    // SDL CALLS //

    SDL_Surface *songSurface;
    SDL_Color songColor = {255, 255, 255};
    songSurface = TTF_RenderUTF8_Blended(songNameFont, songChar, songColor);
    TTF_SizeText(songNameFont, songChar, &songWidth, &songHeight);
    SDL_Rect songLocation = {musicbarSurfaceWidth/2 - songWidth/2, musicbarSurfaceHeight/2 - songHeight/2, 0, 0};
    SDL_BlitSurface(songSurface, NULL, surface, &songLocation);
    SDL_FreeSurface(songSurface);
}

std::string MusicBar::convertToString(int songIntTime)
{
    std::string songStringTime;

    std::stringstream convertSongIntTime;
    convertSongIntTime << songIntTime;
    songStringTime = convertSongIntTime.str();

    return songStringTime;
}

void MusicBar::drawSongTime()
{
    double songCurrentTime;
    int songCurrentMins;
    int songCurrentSecs;
    double songCurrentPercent;
    int songCurrentIntTime;

    std::string songCurrentStrTime;
    std::string songCurrentStrMins;
    std::string songCurrentStrSecs;
    const char * songCurrentCharTime;

    double songTotalTime;
    int songTotalMins;
    int songTotalSecs;
    int songTotalIntTime;

    std::string songTotalStrTime;
    std::string songTotalStrMins;
    std::string songTotalStrSecs;
    const char * songTotalCharTime;

    int totalTimeWidth;
    int totalTimeHeight;

    songCurrentTime = mPlayer->getCurrentTime();
    songTotalTime = mPlayer->getSongLength();

    songCurrentPercent = songCurrentTime / songTotalTime;
    songCurrentIntTime = songCurrentTime;
    songCurrentMins = songCurrentIntTime / 60;
    songCurrentSecs = songCurrentIntTime % 60;

    //songTotalTime = songTotalTime - songCurrentTime; // Remove to stop end time increment
    songTotalIntTime = songTotalTime;
    songTotalMins = songTotalTime / 60;
    songTotalSecs = songTotalIntTime % 60;

    songCurrentStrMins = convertToString(songCurrentMins);
    songCurrentStrSecs = convertToString(songCurrentSecs);

    if (songCurrentSecs < 10)
    {
        songCurrentStrTime = songCurrentStrMins + ":0" +
                                songCurrentStrSecs;
    }
    else
    {
        songCurrentStrTime = songCurrentStrMins + ":" + songCurrentStrSecs;
    }

    songCurrentCharTime = songCurrentStrTime.c_str();

    songTotalStrMins = convertToString(songTotalMins);
    songTotalStrSecs = convertToString(songTotalSecs);

    if (songTotalSecs < 10)
    {
        songTotalStrTime = songTotalStrMins + ":0" + songTotalStrSecs;
    }
    else
    {
        songTotalStrTime = songTotalStrMins + ":" + songTotalStrSecs;
    }

    songTotalCharTime =  songTotalStrTime.c_str();

    // SDL CALLS//

    SDL_Color songTimeColor = {255, 255, 255};

    SDL_Surface *songCurrentTimeSurface;
    songCurrentTimeSurface = TTF_RenderText_Blended(timeFont, songCurrentCharTime, songTimeColor);
    SDL_Rect songCurrentTimeLocation = {0, 4, 0, 0};
    SDL_BlitSurface(songCurrentTimeSurface, NULL, surface, &songCurrentTimeLocation);
    SDL_FreeSurface(songCurrentTimeSurface);

    SDL_Surface *songTotalTimeSurface;
    songTotalTimeSurface = TTF_RenderText_Blended(timeFont, songTotalCharTime, songTimeColor);
    TTF_SizeText(timeFont, songTotalCharTime, &totalTimeWidth, &totalTimeHeight);
    SDL_Rect songTotalTimeLocation = {musicbarSurfaceWidth - totalTimeWidth, 4, 0};
    SDL_BlitSurface(songTotalTimeSurface, NULL, surface, &songTotalTimeLocation);
    SDL_FreeSurface(songTotalTimeSurface);

    SDL_Surface *songTimebarSurface;
    songTimebarSurface = SDL_CreateRGBSurface(0, 0 + songCurrentPercent*musicbarSurfaceWidth, 3, 32, 0, 0, 0, 0);
    SDL_FillRect(songTimebarSurface, NULL, SDL_MapRGB(songTimebarSurface->format,0,162,255));
    SDL_Rect songTimebarLocation = {0, 0, 0, 0};
    SDL_BlitSurface(songTimebarSurface, NULL, surface, &songTimebarLocation);
    SDL_FreeSurface(songTimebarSurface);
}

void MusicBar::drawVolumeBar()
{
    double songVolumeCurrent;
    double songVolumePercent;
    double songVolumeMax;
    songVolumeMax = 2.0;

    songVolumeCurrent = mPlayer->getVolume();

    songVolumePercent = songVolumeCurrent / songVolumeMax;

    // Volume Background Bar
    SDL_Surface *volumeBackgroundSurface;
    int volumeBarHeight;
    int volumeBarXLocation;
    int volumeBarYLocation;
    int volumeBarNumber;
    int i;
    int colorGreen;

    volumeBarNumber = 20;
    volumeBarHeight = 4;
    volumeBarXLocation = 880;
    volumeBarYLocation = 50;

    for (i = 0; i < volumeBarNumber; i++)
    {
        volumeBackgroundSurface = SDL_CreateRGBSurface(0,4, volumeBarHeight,32,0,0,0,0);
        SDL_FillRect(volumeBackgroundSurface, NULL, SDL_MapRGB(volumeBackgroundSurface->format,0,0,0));
        SDL_Rect volumeBarLocation = {volumeBarXLocation,volumeBarYLocation,0,0};
        SDL_BlitSurface(volumeBackgroundSurface, NULL, surface, &volumeBarLocation);
        SDL_FreeSurface(volumeBackgroundSurface);

        //Increments for changing bar size
        volumeBarHeight += 2;
        volumeBarXLocation += 6;
        volumeBarYLocation -= 2;
    }

    // Volume bar
    SDL_Surface *volumeSurface;

    volumeBarHeight = 4;
    volumeBarXLocation = 880;
    volumeBarYLocation = 50;
    colorGreen = 162;
    songVolumePercent = songVolumePercent * volumeBarNumber - 0.1;

    for (i = 0; i < songVolumePercent; i++)
    {
        volumeSurface = SDL_CreateRGBSurface(0,4, volumeBarHeight, 32,0,0,0,0);
        SDL_FillRect(volumeSurface, NULL, SDL_MapRGB(volumeSurface->format,255,colorGreen,0));
        SDL_Rect volumeBarLocation = {volumeBarXLocation, volumeBarYLocation, 0, 0};
        SDL_BlitSurface(volumeSurface, NULL, surface, &volumeBarLocation);
        SDL_FreeSurface(volumeSurface);

        // Increments for changing bar size and gradient
        volumeBarHeight += 2;
        colorGreen -= 6;
        volumeBarXLocation += 6;
        volumeBarYLocation -= 2;
    }
}

void MusicBar::update()
{
    SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format,43,43,43));
    drawSongName();
    drawSongTime();
    drawVolumeBar();
}

SDL_Surface* MusicBar::returnMusicBar()
{
    return surface;
}

<commit_msg>Fonts are now looking at /usr/share/fonts<commit_after>#include "MusicBar.h"

MusicBar::MusicBar(SongPlayer *songPlayer)
{
    mPlayer = songPlayer;
    musicbarSurfaceWidth = 1080;
    musicbarSurfaceHeight = 64;
    surface = SDL_CreateRGBSurface(0, musicbarSurfaceWidth, musicbarSurfaceHeight, 32, 0, 0, 0, 0);
    init();
}

int MusicBar::init()
{
    int songNameFontSize;
    int timeFontSize;

    songNameFontSize = 45;
    timeFontSize = 25;

    if (TTF_Init() !=0)
    {
        fprintf(stderr, "TTF_Init Failed%s\n", TTF_GetError());
        SDL_Quit();
        exit(1);
    }

    songNameFont = TTF_OpenFont("/usr/share/fonts/ant-maru.ttf", songNameFontSize);
    if (songNameFont == NULL)
    {
        fprintf(stderr, "TTF_OpenFont Failed%s\n", TTF_GetError());
        TTF_Quit();
        SDL_Quit();
        exit(1);
    }

    timeFont = TTF_OpenFont("/usr/share/fonts/Trebuchet-MS.ttf", timeFontSize);
    if (timeFont == NULL)
    {
        fprintf(stderr, "TTF_OpenFont Failed%s\n", TTF_GetError());
        TTF_Quit();
        SDL_Quit();
        exit(1);
    }
}

void MusicBar::drawSongName()
{
    std::string songName;
    int songStringLength;
    const char * songChar;
    int songWidth;
    int songHeight;

    songName = mPlayer->currentSong();
    songStringLength = songName.length();
    songName = songName.substr(12, songStringLength - 16); // removes SongLibrary/ and .mp3 from songName
    songChar = songName.c_str();

    // SDL CALLS //

    SDL_Surface *songSurface;
    SDL_Color songColor = {255, 255, 255};
    songSurface = TTF_RenderUTF8_Blended(songNameFont, songChar, songColor);
    TTF_SizeText(songNameFont, songChar, &songWidth, &songHeight);
    SDL_Rect songLocation = {musicbarSurfaceWidth/2 - songWidth/2, musicbarSurfaceHeight/2 - songHeight/2, 0, 0};
    SDL_BlitSurface(songSurface, NULL, surface, &songLocation);
    SDL_FreeSurface(songSurface);
}

std::string MusicBar::convertToString(int songIntTime)
{
    std::string songStringTime;

    std::stringstream convertSongIntTime;
    convertSongIntTime << songIntTime;
    songStringTime = convertSongIntTime.str();

    return songStringTime;
}

void MusicBar::drawSongTime()
{
    double songCurrentTime;
    int songCurrentMins;
    int songCurrentSecs;
    double songCurrentPercent;
    int songCurrentIntTime;

    std::string songCurrentStrTime;
    std::string songCurrentStrMins;
    std::string songCurrentStrSecs;
    const char * songCurrentCharTime;

    double songTotalTime;
    int songTotalMins;
    int songTotalSecs;
    int songTotalIntTime;

    std::string songTotalStrTime;
    std::string songTotalStrMins;
    std::string songTotalStrSecs;
    const char * songTotalCharTime;

    int totalTimeWidth;
    int totalTimeHeight;

    songCurrentTime = mPlayer->getCurrentTime();
    songTotalTime = mPlayer->getSongLength();

    songCurrentPercent = songCurrentTime / songTotalTime;
    songCurrentIntTime = songCurrentTime;
    songCurrentMins = songCurrentIntTime / 60;
    songCurrentSecs = songCurrentIntTime % 60;

    //songTotalTime = songTotalTime - songCurrentTime; // Remove to stop end time increment
    songTotalIntTime = songTotalTime;
    songTotalMins = songTotalTime / 60;
    songTotalSecs = songTotalIntTime % 60;

    songCurrentStrMins = convertToString(songCurrentMins);
    songCurrentStrSecs = convertToString(songCurrentSecs);

    if (songCurrentSecs < 10)
    {
        songCurrentStrTime = songCurrentStrMins + ":0" +
                                songCurrentStrSecs;
    }
    else
    {
        songCurrentStrTime = songCurrentStrMins + ":" + songCurrentStrSecs;
    }

    songCurrentCharTime = songCurrentStrTime.c_str();

    songTotalStrMins = convertToString(songTotalMins);
    songTotalStrSecs = convertToString(songTotalSecs);

    if (songTotalSecs < 10)
    {
        songTotalStrTime = songTotalStrMins + ":0" + songTotalStrSecs;
    }
    else
    {
        songTotalStrTime = songTotalStrMins + ":" + songTotalStrSecs;
    }

    songTotalCharTime =  songTotalStrTime.c_str();

    // SDL CALLS//

    SDL_Color songTimeColor = {255, 255, 255};

    SDL_Surface *songCurrentTimeSurface;
    songCurrentTimeSurface = TTF_RenderText_Blended(timeFont, songCurrentCharTime, songTimeColor);
    SDL_Rect songCurrentTimeLocation = {0, 4, 0, 0};
    SDL_BlitSurface(songCurrentTimeSurface, NULL, surface, &songCurrentTimeLocation);
    SDL_FreeSurface(songCurrentTimeSurface);

    SDL_Surface *songTotalTimeSurface;
    songTotalTimeSurface = TTF_RenderText_Blended(timeFont, songTotalCharTime, songTimeColor);
    TTF_SizeText(timeFont, songTotalCharTime, &totalTimeWidth, &totalTimeHeight);
    SDL_Rect songTotalTimeLocation = {musicbarSurfaceWidth - totalTimeWidth, 4, 0};
    SDL_BlitSurface(songTotalTimeSurface, NULL, surface, &songTotalTimeLocation);
    SDL_FreeSurface(songTotalTimeSurface);

    SDL_Surface *songTimebarSurface;
    songTimebarSurface = SDL_CreateRGBSurface(0, 0 + songCurrentPercent*musicbarSurfaceWidth, 3, 32, 0, 0, 0, 0);
    SDL_FillRect(songTimebarSurface, NULL, SDL_MapRGB(songTimebarSurface->format,0,162,255));
    SDL_Rect songTimebarLocation = {0, 0, 0, 0};
    SDL_BlitSurface(songTimebarSurface, NULL, surface, &songTimebarLocation);
    SDL_FreeSurface(songTimebarSurface);
}

void MusicBar::drawVolumeBar()
{
    double songVolumeCurrent;
    double songVolumePercent;
    double songVolumeMax;
    songVolumeMax = 2.0;

    songVolumeCurrent = mPlayer->getVolume();

    songVolumePercent = songVolumeCurrent / songVolumeMax;

    // Volume Background Bar
    SDL_Surface *volumeBackgroundSurface;
    int volumeBarHeight;
    int volumeBarXLocation;
    int volumeBarYLocation;
    int volumeBarNumber;
    int i;
    int colorGreen;

    volumeBarNumber = 20;
    volumeBarHeight = 4;
    volumeBarXLocation = 880;
    volumeBarYLocation = 50;

    for (i = 0; i < volumeBarNumber; i++)
    {
        volumeBackgroundSurface = SDL_CreateRGBSurface(0,4, volumeBarHeight,32,0,0,0,0);
        SDL_FillRect(volumeBackgroundSurface, NULL, SDL_MapRGB(volumeBackgroundSurface->format,0,0,0));
        SDL_Rect volumeBarLocation = {volumeBarXLocation,volumeBarYLocation,0,0};
        SDL_BlitSurface(volumeBackgroundSurface, NULL, surface, &volumeBarLocation);
        SDL_FreeSurface(volumeBackgroundSurface);

        //Increments for changing bar size
        volumeBarHeight += 2;
        volumeBarXLocation += 6;
        volumeBarYLocation -= 2;
    }

    // Volume bar
    SDL_Surface *volumeSurface;

    volumeBarHeight = 4;
    volumeBarXLocation = 880;
    volumeBarYLocation = 50;
    colorGreen = 162;
    songVolumePercent = songVolumePercent * volumeBarNumber - 0.1;

    for (i = 0; i < songVolumePercent; i++)
    {
        volumeSurface = SDL_CreateRGBSurface(0,4, volumeBarHeight, 32,0,0,0,0);
        SDL_FillRect(volumeSurface, NULL, SDL_MapRGB(volumeSurface->format,255,colorGreen,0));
        SDL_Rect volumeBarLocation = {volumeBarXLocation, volumeBarYLocation, 0, 0};
        SDL_BlitSurface(volumeSurface, NULL, surface, &volumeBarLocation);
        SDL_FreeSurface(volumeSurface);

        // Increments for changing bar size and gradient
        volumeBarHeight += 2;
        colorGreen -= 6;
        volumeBarXLocation += 6;
        volumeBarYLocation -= 2;
    }
}

void MusicBar::update()
{
    SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format,43,43,43));
    drawSongName();
    drawSongTime();
    drawVolumeBar();
}

SDL_Surface* MusicBar::returnMusicBar()
{
    return surface;
}

<|endoftext|>


<commit_before>#include "commentTab.h"
#include "patch.h"
#include <time.h>
#include "win32.h"
#include <stdexcept>

using namespace std;

void commentTabChtml::indentHtml(ostream& stream, int indent) {
}

void commentTabChtml::indentEndHtml(ostream& stream) {
}

const char* commentTabChtml::patch(const char* date) {
	// parse string date to time_t
	// search through patch version list
	struct tm tm;
	const char* res = strptime(date, "%Y/%m/%d %T", &tm);
	if(!res)
		throw logic_error("commentTabChtml::patch: strptime failed");
	time_t t = timegm(&tm);
	for(int i=0; i<gnPatchVersions; i++) {
		if(t < gPatchVersions[i].time)
			return gPatchVersions[i].name;
	}
	throw logic_error("commentTabChtml::patch: invalid date");
}
<commit_msg>Comments: Fixed patch calculation.<commit_after>#include "commentTab.h"
#include "patch.h"
#include <time.h>
#include "win32.h"
#include <stdexcept>

using namespace std;

void commentTabChtml::indentHtml(ostream& stream, int indent) {
}

void commentTabChtml::indentEndHtml(ostream& stream) {
}

const char* commentTabChtml::patch(const char* date) {
	// parse string date to time_t
	// search through patch version list
	struct tm tm;
	const char* res = strptime(date, "%Y/%m/%d %T", &tm);
	if(!res)
		throw logic_error("commentTabChtml::patch: strptime failed");
	time_t t = timegm(&tm);
	for(int i=1; i<gnPatchVersions; i++) {
		if(t < gPatchVersions[i].time)
			return gPatchVersions[i-1].name;
	}
	throw logic_error("commentTabChtml::patch: invalid date");
}
<|endoftext|>


<commit_before>#include "DRAW.H"

#include "CONTROL.H"
#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "DRAWSPKS.H"
#include "SETUP.H"
#include "MATHS.H"
#endif

#include "OBJECTS.H"

#include "SPECIFIC.H"
#include "STYPES.H"
#include "TOMB4FX.H"
#include <stddef.h>
//#include <INLINE_O.H>
#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "MISC.H"
#endif

short LightningSFXDelay;
struct room_info* room;
short number_rooms;
long* bones;
struct ANIM_STRUCT* anims;
struct RANGE_STRUCT* ranges;
struct CHANGE_STRUCT* changes;
short** meshes;
short* commands;
short* frames;
short* binoculars_mesh_ptr;
short* target_mesh_ptr;
short SkyPos;
short SkyPos2;
int number_draw_rooms;
short draw_rooms[100];
int number_dynamics;
long camera_underwater;
long gfMirrorZPlane;
unsigned short LightningRGBs[3];
unsigned short LightningRGB[3];
short LightningCount;
short LightningRand;
short dLightningRand;
short interpolated_bounds[6];
short* GLOBAL_gunflash_meshptr;
int CurrentRoom;
unsigned char CreditsDone;
short GlobalRoomNumber;
long outside;
long outside_left;
long outside_right;
long outside_top;
long outside_bottom;
short HorizonClip;
struct door_vbuf vbufdoor[4];
short Sback_gun;
short* SRhandPtr;
short* SLhandPtr;

#if PC_VERSION || PSXPC_TEST
long GetFrames(struct ITEM_INFO* item/*$a0*/, short* frames[]/*a1*/, int* rate/*$a2*/)//8582C
{
	struct ANIM_STRUCT* anim = &anims[item->anim_number];
	int t3;
	short* t4;

	rate[0] = anim->interpolation;

	t3 = ((item->frame_number - anim->frame_base) / anim->interpolation) * anim->interpolation >> 8;
	t4 = &anim->frame_ptr[t3];

	frames[0] = &anim->frame_ptr[t3];
	frames[1] = &t4[anim->interpolation >> 8];
	if (anim->interpolation == 0)
	{
		return 0;
	}

	t3 = ((item->frame_number - anim->frame_base) / anim->interpolation) * anim->interpolation;

	if (!(anim->frame_end < (t3 + anim->interpolation)))
	{
		return (t3 + anim->interpolation) - anim->interpolation;
	}

	rate[0] = anim->frame_end - anim->interpolation;
	return (item->frame_number - anim->frame_base) / anim->interpolation;
}
#endif

void UpdateSkyLightning()//2C0D0(<), ? (F)
{
	long lp;

	if (LightningCount > 0)
	{
		--LightningCount;

		if ((LightningCount << 16) == 0)
		{
			LightningRand = (GetRandomDraw() & 0x7F) + 400;
			dLightningRand = 0;
		}
		else
		{
			//loc_2C118
			dLightningRand = (GetRandomDraw() & 0x1FF);
			LightningRand = ((dLightningRand - LightningRand) >> 1) + LightningRand;
		}
	}
	else
	{
		//loc_2C148
		if (LightningRand < 4)
		{
			//loc_2C174
			LightningRand = 0;
		}
		else
		{
			LightningRand = LightningRand - (LightningRand >> 2);
		}
	}

	//loc_2C18C
	for (lp = 2; lp >= 0; lp--)
	{
		LightningRGBs[lp] += ((LightningRGBs[lp] * LightningRand) >> 8);
		if ((LightningRGBs[lp] & 0xFFFF) > 255)
		{
			LightningRGBs[lp] = 255;
		}
	}
}

void DrawSkyMesh(short* mesh)
{
	UNIMPLEMENTED();
}

void DrawMoon()
{
	UNIMPLEMENTED();
}

void DrawGunflashes()//8A924(<) 8C968(<)
{
#ifdef PC_VERSION
	UNIMPLEMENTED();
#else
	long rand;
	long i;
	short* mesh;

	if (!Gunflashes[0].on)
	{
		return;
	}

	mPushMatrix();
	rand = (GetRandomDraw() & 0x1F);

	/*SetInventoryLighting(((GetRandomDraw() & 0xF) + 72) | 0x4000,
		((GetRandomDraw() & 0xF) + 72) | 0x4000,
		((GetRandomDraw() & 0xF) + 72) | 0x4000,
		rand << 16 | rand << 8 | rand);*/

	for (i = 0; i < 4; i++)
	{
		if (Gunflashes[i].on)
		{
			mCopyMatrix(&Gunflashes[i].matrix);
			//mRotZ(GetRandomDraw() << 1);
			mesh = meshes[objects[GUN_FLASH].mesh_index];
			//phd_PutPolygons(((long*) mesh)[0], -1);
			mesh[16] = 0;
		}
	}

	mPopMatrix();
#endif
}

short* GetBestFrame(struct ITEM_INFO* item)// (F)s
{
	short* frm[2];
	int rate;
	const int ret = GetFrames(item, frm, &rate);

	if (ret > (rate >> 1))
		return frm[1];
	else
		return frm[0];
}

void DrawAnimatingItem(struct ITEM_INFO *item)
{
	UNIMPLEMENTED();
}<commit_msg>Fix PSX compile<commit_after>#include "DRAW.H"

#include "CONTROL.H"
#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "DRAWSPKS.H"
#include "SETUP.H"
#include "MATHS.H"
#endif

#include "OBJECTS.H"

#include "SPECIFIC.H"
#include "STYPES.H"
#include "TOMB4FX.H"
#include <stddef.h>
//#include <INLINE_O.H>
#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "MISC.H"
#endif

short LightningSFXDelay;
struct room_info* room;
short number_rooms;
long* bones;
struct ANIM_STRUCT* anims;
struct RANGE_STRUCT* ranges;
struct CHANGE_STRUCT* changes;
short** meshes;
short* commands;
short* frames;
short* binoculars_mesh_ptr;
short* target_mesh_ptr;
short SkyPos;
short SkyPos2;
int number_draw_rooms;
short draw_rooms[100];
int number_dynamics;
long camera_underwater;
long gfMirrorZPlane;
unsigned short LightningRGBs[3];
unsigned short LightningRGB[3];
short LightningCount;
short LightningRand;
short dLightningRand;
short interpolated_bounds[6];
short* GLOBAL_gunflash_meshptr;
int CurrentRoom;
unsigned char CreditsDone;
short GlobalRoomNumber;
long outside;
long outside_left;
long outside_right;
long outside_top;
long outside_bottom;
short HorizonClip;
struct door_vbuf vbufdoor[4];
short Sback_gun;
short* SRhandPtr;
short* SLhandPtr;

#if PC_VERSION || PSXPC_TEST
long GetFrames(struct ITEM_INFO* item/*$a0*/, short* frames[]/*a1*/, int* rate/*$a2*/)//8582C
{
	struct ANIM_STRUCT* anim = &anims[item->anim_number];
	int t3;
	short* t4;

	rate[0] = anim->interpolation;

	t3 = ((item->frame_number - anim->frame_base) / anim->interpolation) * anim->interpolation >> 8;
	t4 = &anim->frame_ptr[t3];

	frames[0] = &anim->frame_ptr[t3];
	frames[1] = &t4[anim->interpolation >> 8];
	if (anim->interpolation == 0)
	{
		return 0;
	}

	t3 = ((item->frame_number - anim->frame_base) / anim->interpolation) * anim->interpolation;

	if (!(anim->frame_end < (t3 + anim->interpolation)))
	{
		return (t3 + anim->interpolation) - anim->interpolation;
	}

	rate[0] = anim->frame_end - anim->interpolation;
	return (item->frame_number - anim->frame_base) / anim->interpolation;
}
#endif

void UpdateSkyLightning()//2C0D0(<), ? (F)
{
	long lp;

	if (LightningCount > 0)
	{
		--LightningCount;

		if ((LightningCount << 16) == 0)
		{
			LightningRand = (GetRandomDraw() & 0x7F) + 400;
			dLightningRand = 0;
		}
		else
		{
			//loc_2C118
			dLightningRand = (GetRandomDraw() & 0x1FF);
			LightningRand = ((dLightningRand - LightningRand) >> 1) + LightningRand;
		}
	}
	else
	{
		//loc_2C148
		if (LightningRand < 4)
		{
			//loc_2C174
			LightningRand = 0;
		}
		else
		{
			LightningRand = LightningRand - (LightningRand >> 2);
		}
	}

	//loc_2C18C
	for (lp = 2; lp >= 0; lp--)
	{
		LightningRGBs[lp] += ((LightningRGBs[lp] * LightningRand) >> 8);
		if ((LightningRGBs[lp] & 0xFFFF) > 255)
		{
			LightningRGBs[lp] = 255;
		}
	}
}

#if PC_VERSION || PSXPC_TEST
void DrawSkyMesh(short* mesh)
{
	UNIMPLEMENTED();
}

void DrawMoon()
{
	UNIMPLEMENTED();
}

#endif
void DrawGunflashes()//8A924(<) 8C968(<)
{
#ifdef PC_VERSION
	UNIMPLEMENTED();
#else
	long rand;
	long i;
	short* mesh;

	if (!Gunflashes[0].on)
	{
		return;
	}

	mPushMatrix();
	rand = (GetRandomDraw() & 0x1F);

	/*SetInventoryLighting(((GetRandomDraw() & 0xF) + 72) | 0x4000,
		((GetRandomDraw() & 0xF) + 72) | 0x4000,
		((GetRandomDraw() & 0xF) + 72) | 0x4000,
		rand << 16 | rand << 8 | rand);*/

	for (i = 0; i < 4; i++)
	{
		if (Gunflashes[i].on)
		{
			mCopyMatrix(&Gunflashes[i].matrix);
			//mRotZ(GetRandomDraw() << 1);
			mesh = meshes[objects[GUN_FLASH].mesh_index];
			//phd_PutPolygons(((long*) mesh)[0], -1);
			mesh[16] = 0;
		}
	}

	mPopMatrix();
#endif
}

short* GetBestFrame(struct ITEM_INFO* item)// (F)s
{
	short* frm[2];
	int rate;
	const int ret = GetFrames(item, frm, &rate);

	if (ret > (rate >> 1))
		return frm[1];
	else
		return frm[0];
}

void DrawAnimatingItem(struct ITEM_INFO *item)
{
	UNIMPLEMENTED();
}<|endoftext|>