<commit_before>/* util.cpp

Copyright (c) 2014, tuxuser. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

*/

#include <QtEndian>
#include <QDirIterator>
#include <QDateTime>
#include <QUuid>
#include <plist/Plist.hpp>
#include "ffs/kextconvert.h"
#include "dsdt2bios/Dsdt2Bios.h"
#include "../ffs.h"
#include "util.h"

/* General stuff */

UINT8 fileOpen(QString path, QByteArray & buf)
{
    QFileInfo fileInfo(path);

    if (!fileInfo.exists())
        return ERR_FILE_NOT_FOUND;

    QFile inputFile;
    inputFile.setFileName(path);

    if (!inputFile.open(QFile::ReadOnly))
        return ERR_FILE_OPEN;

    buf.clear();

    buf.append(inputFile.readAll());
    inputFile.close();

    return ERR_SUCCESS;
}

UINT8 fileWrite(QString path, QByteArray & buf)
{
    QFileInfo fileInfo(path);

    if (fileInfo.exists())
        printf("Warning: File already exists! Overwriting it...\n");

    QFile writeFile;
    writeFile.setFileName(path);

    if (!writeFile.open(QFile::WriteOnly))
        return ERR_FILE_OPEN;

    if(writeFile.write(buf) != buf.size())
        return ERR_FILE_WRITE;

    writeFile.close();

    return ERR_SUCCESS;
}

BOOLEAN fileExists(QString path)
{
    QFileInfo fileInfo = QFileInfo(path);

    return fileInfo.exists();
}

UINT8 dirCreate(QString path)
{
    QDir dir;
    if (dir.cd(path))
        return ERR_DIR_ALREADY_EXIST;

    if (!dir.mkpath(path))
        return ERR_DIR_CREATE;

    return ERR_SUCCESS;
}

BOOLEAN dirExists(QString path)
{
    QDir dir(path);

    return dir.exists();
}

QString pathConcatenate(QString path, QString filename)
{
    return QDir(path).filePath(filename);
}

UINT32 getDateTime()
{
    QDateTime dateTime = QDateTime::currentDateTime();
    return dateTime.toTime_t();
}

UINT16 getUInt16(QByteArray & buf, UINT32 start, bool fromBE)
{
    UINT16 tmp = 0;

    tmp = (tmp << 8) + buf.at(start+0);
    tmp = (tmp << 8) + buf.at(start+1);

    if(fromBE)
        return qFromBigEndian(tmp);
    else
        return tmp;
}

UINT32 getUInt32(QByteArray & buf, UINT32 start, bool fromBE)
{
    UINT32 tmp = 0;

    tmp = (tmp << 8) + buf.at(start+0);
    tmp = (tmp << 8) + buf.at(start+1);
    tmp = (tmp << 8) + buf.at(start+2);
    tmp = (tmp << 8) + buf.at(start+3);

    if(fromBE)
        return qFromBigEndian(tmp);
    else
        return tmp;
}

/* Specific stuff */

UINT8 getGUIDfromFile(QByteArray object, QString & name)
{
    QByteArray header;
    EFI_GUID* guid;
    header = object.left(sizeof(EFI_GUID));
    guid = (EFI_GUID*)(header.constData());

    // Get info
    name = guidToQString(*guid);
    return ERR_SUCCESS;
}

UINT8 plistReadExecName(QByteArray plist, QString & name)
{
    static const std::string execIdentifier = "CFBundleExecutable";

    QString plistExec;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(execIdentifier) > 0)
        plistExec = boost::any_cast<const std::string&>(dict.find(execIdentifier)->second).c_str();

    if(plistExec.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank. Aborting!\n");
        return ERR_ERROR;
    }

    name = plistExec;

    return ERR_SUCCESS;
}

UINT8 plistReadBundlenameAndVersion(QByteArray plist, QString & name, QString & version)
{
    static const std::string nameIdentifier = "CFBundleName";
    static const std::string versionIdentifier = "CFBundleShortVersionString";

    QString plistName;
    QString plistVersion;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(nameIdentifier) > 0)
        plistName = boost::any_cast<const std::string&>(dict.find(nameIdentifier)->second).c_str();

    if(dict.count(versionIdentifier) > 0)
        plistVersion = boost::any_cast<const std::string&>(dict.find(versionIdentifier)->second).c_str();

    if(plistName.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank. Aborting!\n");
        return ERR_ERROR;
    }

    name = plistName;
    version = plistVersion;

    return ERR_SUCCESS;
}

UINT8 plistWriteNewBasename(QByteArray plist, QString newName, QByteArray & out)
{
    std::vector<char> data;
    static const std::string nameIdentifier = "CFBundleName";

    QString plistName;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(nameIdentifier) > 0)
        plistName = boost::any_cast<const std::string&>(dict.find(nameIdentifier)->second).c_str();

    if(plistName.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank, so cannot be modified. Aborting!\n");
        return ERR_ERROR;
    }

    // Assign new value for CFBundleName
    dict[nameIdentifier] = std::string(newName.toUtf8().constData());

    Plist::writePlistXML(data, dict);

    out.clear();
    out.append(data.data(), data.size());

    return ERR_SUCCESS;
}

UINT8 checkAggressivityLevel(int aggressivity) {
    QString level;

    switch(aggressivity) {
    case RUN_AS_IS:
        level = "Do nothing - Inject as-is";
        break;
    case RUN_COMPRESS:
         level = "Compress CORE_DXE";
         break;
    case RUN_DELETE:
         level = "Delete network stuff from BIOS";
         break;
    case RUN_DEL_OZM_NREQ:
         level = "Delete non-required Ozmosis files";
         break;
    default:
        printf("Warning: Invalid aggressivity level set!\n");
        return ERR_ERROR;
    }

    printf("Info: Aggressivity level set to '%s'...\n", qPrintable(level));
    return ERR_SUCCESS;
}

UINT8 convertOzmPlist(QString input, QByteArray & out)
{
    UINT8 ret;
    QByteArray plist;

    KextConvert *kext = new KextConvert();

    ret = fileOpen(input, plist);
    if(ret) {
        printf("ERROR: Open failed: %s\n", qPrintable(input));
        return ERR_ERROR;
    }

    ret = kext->createFFS(ozmSectionName, ozmPlistGUID, plist, out);
    if(ret) {
        printf("ERROR: KEXT2FFS failed on '%s'\n", qPrintable(ozmDefaultsFilename));
        return ERR_ERROR;
    }

    return ERR_SUCCESS;
}

UINT8 convertKext(QString input, int kextIndex, QByteArray & out)
{
    UINT8 ret;
    UINT8 nullterminator = 0;

    QString sectionName, guid;
    QString bundleName, bundleVersion, execName;
    QDir dir;

    QFileInfo binaryPath;
    QFileInfo plistPath;

    QByteArray plistbuf;
    QByteArray binarybuf;
    QByteArray toConvertBinary;

    KextConvert *kext = new KextConvert();

    // Check all folders in input-dir

    if(kextIndex > 0xF) {
        printf("ERROR: Invalid kextIndex '%i' supplied!\n", kextIndex);
        return ERR_ERROR;
    }

    dir.setPath(input);
    dir = dir.filePath("Contents");
    plistPath.setFile(dir,"Info.plist");
    dir = dir.filePath("MacOS");

    if (!dir.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/MacOS/ missing!\n");
        return ERR_ERROR;
    }

    if (!plistPath.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/Info.plist missing!\n");
        return ERR_ERROR;
    }

    ret = fileOpen(plistPath.filePath(), plistbuf);
    if(ret) {
        printf("ERROR: Opening '%s' failed!\n", qPrintable(plistPath.filePath()));
        return ret;
    }

    ret = plistReadExecName(plistbuf, execName);
    if(ret) {
        printf("ERROR: Failed to get executableName Info.plist\n");
        return ret;
    }

    binaryPath.setFile(dir, execName);

    if (!binaryPath.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/MacOS/%s missing!\n",
               qPrintable(execName));
        return ERR_ERROR;
    }

    ret = plistReadBundlenameAndVersion(plistbuf, bundleName, bundleVersion);
    if (ret) {
        printf("ERROR: Failed to get bundleName and/or version from Info.plist\n");
        return ret;
    }

    ret = fileOpen(binaryPath.filePath(), binarybuf);
    if (ret) {
        printf("ERROR: Opening '%s' failed!\n", qPrintable(binaryPath.filePath()));
        return ERR_ERROR;
    }

    if(bundleVersion.isEmpty())
        bundleVersion = "?";

    sectionName.sprintf("%s-%s",qPrintable(bundleName), qPrintable(bundleVersion));

    guid = kextGUID.arg(kextIndex, 0, 16);

    toConvertBinary.append(plistbuf);
    toConvertBinary.append(nullterminator);
    toConvertBinary.append(binarybuf);

//    ret = kext->createFFS(sectionName, guid, toConvertBinary, out);
    ret = customFFScreate(toConvertBinary, guid, sectionName, out);
    if(ret) {
        printf("ERROR: KEXT2FFS failed on '%s'\n", qPrintable(sectionName));
        return ERR_ERROR;
    }

    return ERR_SUCCESS;
}

UINT8 customFFScreate(QByteArray body, QString guid, QString sectionName, QByteArray & out)
{
    QByteArray bufSectionName;
    QByteArray bufFileHdr, bufPE32SectionHdr, bufUserInterfaceSectionHdr;
//    QByteArray bufPE32Section, bufUserInterfaceSection;
    QByteArray fileBody;

    /* FFS PE32 Section */
    bufPE32SectionHdr.fill(0, sizeof(EFI_COMMON_SECTION_HEADER));
    EFI_COMMON_SECTION_HEADER* PE32SectionHeader = (EFI_COMMON_SECTION_HEADER*)bufPE32SectionHdr.data();

    uint32ToUint24(sizeof(EFI_COMMON_SECTION_HEADER)+body.size(), PE32SectionHeader->Size);
    PE32SectionHeader->Type = EFI_SECTION_PE32;

    fileBody.append(bufPE32SectionHdr);
    fileBody.append(body);

    /* FFS User Interface */
    bufUserInterfaceSectionHdr.fill(0, sizeof(EFI_USER_INTERFACE_SECTION));
    EFI_USER_INTERFACE_SECTION* UserInterfaceSection = (EFI_USER_INTERFACE_SECTION*)bufUserInterfaceSectionHdr.data();

    /* Convert sectionName to unicode data */
    bufSectionName.append((const char*) (sectionName.utf16()), sectionName.size() * 2);

    uint32ToUint24(sizeof(EFI_USER_INTERFACE_SECTION)+bufSectionName.size(), UserInterfaceSection->Size);
    UserInterfaceSection->Type = EFI_SECTION_USER_INTERFACE;

    fileBody.append(bufUserInterfaceSectionHdr);
    fileBody.append(bufSectionName);

    /* FFS File */
    const static UINT8 erasePolarity = 0;
    const static UINT8 revision = 0;
    const static UINT32 size = fileBody.size();

    QUuid uuid = QUuid(guid);
    QByteArray baGuid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));

    printf("GUID: %s\n",qPrintable(uuid.toString()));

    bufFileHdr = QByteArray(size - baGuid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00');

    bufFileHdr.prepend(baGuid);

    EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*)bufFileHdr.data();
    uint32ToUint24(sizeof(EFI_FFS_FILE_HEADER)+size, fileHeader->Size);
    fileHeader->Attributes = 0x00;
    fileHeader->Type = EFI_FV_FILETYPE_FREEFORM;
    fileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
    // Invert state bits if erase polarity is true
    if (erasePolarity == ERASE_POLARITY_TRUE)
        fileHeader->State = ~fileHeader->State;

    // Calculate header checksum
    fileHeader->IntegrityCheck.Checksum.Header = 0;
    fileHeader->IntegrityCheck.Checksum.File = 0;
    fileHeader->IntegrityCheck.Checksum.Header = calculateChecksum8((UINT8*)fileHeader, sizeof(EFI_FFS_FILE_HEADER)-1);

    // Set data checksum
    if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM)
        fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*)fileBody.constData(), fileBody.size());
    else if (revision == 1)
        fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
    else
        fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2;

    out.clear();
    out.append(bufFileHdr, sizeof(EFI_FFS_FILE_HEADER));
    out.append(fileBody);

    fileWrite("/Users/tuxuser/Desktop/ALF.ffs", out);

    return ERR_SUCCESS;
}
<commit_msg>ALF... likes to eat cats<commit_after>/* util.cpp

Copyright (c) 2014, tuxuser. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

*/

#include <QtEndian>
#include <QDirIterator>
#include <QDateTime>
#include <QUuid>
#include <plist/Plist.hpp>
#include "ffs/kextconvert.h"
#include "dsdt2bios/Dsdt2Bios.h"
#include "../ffs.h"
#include "util.h"

/* General stuff */

UINT8 fileOpen(QString path, QByteArray & buf)
{
    QFileInfo fileInfo(path);

    if (!fileInfo.exists())
        return ERR_FILE_NOT_FOUND;

    QFile inputFile;
    inputFile.setFileName(path);

    if (!inputFile.open(QFile::ReadOnly))
        return ERR_FILE_OPEN;

    buf.clear();

    buf.append(inputFile.readAll());
    inputFile.close();

    return ERR_SUCCESS;
}

UINT8 fileWrite(QString path, QByteArray & buf)
{
    QFileInfo fileInfo(path);

    if (fileInfo.exists())
        printf("Warning: File already exists! Overwriting it...\n");

    QFile writeFile;
    writeFile.setFileName(path);

    if (!writeFile.open(QFile::WriteOnly))
        return ERR_FILE_OPEN;

    if(writeFile.write(buf) != buf.size())
        return ERR_FILE_WRITE;

    writeFile.close();

    return ERR_SUCCESS;
}

BOOLEAN fileExists(QString path)
{
    QFileInfo fileInfo = QFileInfo(path);

    return fileInfo.exists();
}

UINT8 dirCreate(QString path)
{
    QDir dir;
    if (dir.cd(path))
        return ERR_DIR_ALREADY_EXIST;

    if (!dir.mkpath(path))
        return ERR_DIR_CREATE;

    return ERR_SUCCESS;
}

BOOLEAN dirExists(QString path)
{
    QDir dir(path);

    return dir.exists();
}

QString pathConcatenate(QString path, QString filename)
{
    return QDir(path).filePath(filename);
}

UINT32 getDateTime()
{
    QDateTime dateTime = QDateTime::currentDateTime();
    return dateTime.toTime_t();
}

UINT16 getUInt16(QByteArray & buf, UINT32 start, bool fromBE)
{
    UINT16 tmp = 0;

    tmp = (tmp << 8) + buf.at(start+0);
    tmp = (tmp << 8) + buf.at(start+1);

    if(fromBE)
        return qFromBigEndian(tmp);
    else
        return tmp;
}

UINT32 getUInt32(QByteArray & buf, UINT32 start, bool fromBE)
{
    UINT32 tmp = 0;

    tmp = (tmp << 8) + buf.at(start+0);
    tmp = (tmp << 8) + buf.at(start+1);
    tmp = (tmp << 8) + buf.at(start+2);
    tmp = (tmp << 8) + buf.at(start+3);

    if(fromBE)
        return qFromBigEndian(tmp);
    else
        return tmp;
}

/* Specific stuff */

UINT8 getGUIDfromFile(QByteArray object, QString & name)
{
    QByteArray header;
    EFI_GUID* guid;
    header = object.left(sizeof(EFI_GUID));
    guid = (EFI_GUID*)(header.constData());

    // Get info
    name = guidToQString(*guid);
    return ERR_SUCCESS;
}

UINT8 plistReadExecName(QByteArray plist, QString & name)
{
    static const std::string execIdentifier = "CFBundleExecutable";

    QString plistExec;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(execIdentifier) > 0)
        plistExec = boost::any_cast<const std::string&>(dict.find(execIdentifier)->second).c_str();

    if(plistExec.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank. Aborting!\n");
        return ERR_ERROR;
    }

    name = plistExec;

    return ERR_SUCCESS;
}

UINT8 plistReadBundlenameAndVersion(QByteArray plist, QString & name, QString & version)
{
    static const std::string nameIdentifier = "CFBundleName";
    static const std::string versionIdentifier = "CFBundleShortVersionString";

    QString plistName;
    QString plistVersion;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(nameIdentifier) > 0)
        plistName = boost::any_cast<const std::string&>(dict.find(nameIdentifier)->second).c_str();

    if(dict.count(versionIdentifier) > 0)
        plistVersion = boost::any_cast<const std::string&>(dict.find(versionIdentifier)->second).c_str();

    if(plistName.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank. Aborting!\n");
        return ERR_ERROR;
    }

    name = plistName;
    version = plistVersion;

    return ERR_SUCCESS;
}

UINT8 plistWriteNewBasename(QByteArray plist, QString newName, QByteArray & out)
{
    std::vector<char> data;
    static const std::string nameIdentifier = "CFBundleName";

    QString plistName;

    std::map<std::string, boost::any> dict;
    Plist::readPlist(plist.data(), plist.size(), dict);

    if(dict.count(nameIdentifier) > 0)
        plistName = boost::any_cast<const std::string&>(dict.find(nameIdentifier)->second).c_str();

    if(plistName.isEmpty()) {
        printf("ERROR: CFBundleName in plist is blank, so cannot be modified. Aborting!\n");
        return ERR_ERROR;
    }

    // Assign new value for CFBundleName
    dict[nameIdentifier] = std::string(newName.toUtf8().constData());

    Plist::writePlistXML(data, dict);

    out.clear();
    out.append(data.data(), data.size());

    return ERR_SUCCESS;
}

UINT8 checkAggressivityLevel(int aggressivity) {
    QString level;

    switch(aggressivity) {
    case RUN_AS_IS:
        level = "Do nothing - Inject as-is";
        break;
    case RUN_COMPRESS:
         level = "Compress CORE_DXE";
         break;
    case RUN_DELETE:
         level = "Delete network stuff from BIOS";
         break;
    case RUN_DEL_OZM_NREQ:
         level = "Delete non-required Ozmosis files";
         break;
    default:
        printf("Warning: Invalid aggressivity level set!\n");
        return ERR_ERROR;
    }

    printf("Info: Aggressivity level set to '%s'...\n", qPrintable(level));
    return ERR_SUCCESS;
}

UINT8 convertOzmPlist(QString input, QByteArray & out)
{
    UINT8 ret;
    QByteArray plist;

    KextConvert *kext = new KextConvert();

    ret = fileOpen(input, plist);
    if(ret) {
        printf("ERROR: Open failed: %s\n", qPrintable(input));
        return ERR_ERROR;
    }

    ret = kext->createFFS(ozmSectionName, ozmPlistGUID, plist, out);
    if(ret) {
        printf("ERROR: KEXT2FFS failed on '%s'\n", qPrintable(ozmDefaultsFilename));
        return ERR_ERROR;
    }

    return ERR_SUCCESS;
}

UINT8 convertKext(QString input, int kextIndex, QByteArray & out)
{
    UINT8 ret;
    UINT8 nullterminator = 0;

    QString sectionName, guid;
    QString bundleName, bundleVersion, execName;
    QDir dir;

    QFileInfo binaryPath;
    QFileInfo plistPath;

    QByteArray plistbuf;
    QByteArray binarybuf;
    QByteArray toConvertBinary;

    KextConvert *kext = new KextConvert();

    // Check all folders in input-dir

    if(kextIndex > 0xF) {
        printf("ERROR: Invalid kextIndex '%i' supplied!\n", kextIndex);
        return ERR_ERROR;
    }

    dir.setPath(input);
    dir = dir.filePath("Contents");
    plistPath.setFile(dir,"Info.plist");
    dir = dir.filePath("MacOS");

    if (!dir.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/MacOS/ missing!\n");
        return ERR_ERROR;
    }

    if (!plistPath.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/Info.plist missing!\n");
        return ERR_ERROR;
    }

    ret = fileOpen(plistPath.filePath(), plistbuf);
    if(ret) {
        printf("ERROR: Opening '%s' failed!\n", qPrintable(plistPath.filePath()));
        return ret;
    }

    ret = plistReadExecName(plistbuf, execName);
    if(ret) {
        printf("ERROR: Failed to get executableName Info.plist\n");
        return ret;
    }

    binaryPath.setFile(dir, execName);

    if (!binaryPath.exists()) {
        printf("ERROR: Kext-dir invalid: */Contents/MacOS/%s missing!\n",
               qPrintable(execName));
        return ERR_ERROR;
    }

    ret = plistReadBundlenameAndVersion(plistbuf, bundleName, bundleVersion);
    if (ret) {
        printf("ERROR: Failed to get bundleName and/or version from Info.plist\n");
        return ret;
    }

    ret = fileOpen(binaryPath.filePath(), binarybuf);
    if (ret) {
        printf("ERROR: Opening '%s' failed!\n", qPrintable(binaryPath.filePath()));
        return ERR_ERROR;
    }

    if(bundleVersion.isEmpty())
        bundleVersion = "?";

    sectionName.sprintf("%s-%s",qPrintable(bundleName), qPrintable(bundleVersion));

    guid = kextGUID.arg(kextIndex, 0, 16);

    toConvertBinary.append(plistbuf);
    toConvertBinary.append(nullterminator);
    toConvertBinary.append(binarybuf);

//    ret = kext->createFFS(sectionName, guid, toConvertBinary, out);
    ret = customFFScreate(toConvertBinary, guid, sectionName, out);
    if(ret) {
        printf("ERROR: KEXT2FFS failed on '%s'\n", qPrintable(sectionName));
        return ERR_ERROR;
    }

    return ERR_SUCCESS;
}

UINT8 customFFScreate(QByteArray body, QString guid, QString sectionName, QByteArray & out)
{
    QByteArray bufSectionName;
    QByteArray bufFileHdr, bufPE32SectionHdr, bufUserInterfaceSectionHdr;
//    QByteArray bufPE32Section, bufUserInterfaceSection;
    QByteArray fileBody;

    /* FFS PE32 Section */
    bufPE32SectionHdr.fill(0, sizeof(EFI_COMMON_SECTION_HEADER));
    EFI_COMMON_SECTION_HEADER* PE32SectionHeader = (EFI_COMMON_SECTION_HEADER*)bufPE32SectionHdr.data();

    uint32ToUint24(sizeof(EFI_COMMON_SECTION_HEADER)+body.size(), PE32SectionHeader->Size);
    PE32SectionHeader->Type = EFI_SECTION_PE32;

    fileBody.append(bufPE32SectionHdr);
    fileBody.append(body);

    /* FFS User Interface */
    bufUserInterfaceSectionHdr.fill(0, sizeof(EFI_USER_INTERFACE_SECTION));
    EFI_USER_INTERFACE_SECTION* UserInterfaceSection = (EFI_USER_INTERFACE_SECTION*)bufUserInterfaceSectionHdr.data();

    /* Convert sectionName to unicode data */
    bufSectionName.append((const char*) (sectionName.utf16()), sectionName.size() * 2);

    uint32ToUint24(sizeof(EFI_USER_INTERFACE_SECTION)+bufSectionName.size(), UserInterfaceSection->Size);
    UserInterfaceSection->Type = EFI_SECTION_USER_INTERFACE;

    fileBody.append(bufUserInterfaceSectionHdr);
    fileBody.append(bufSectionName);

    /* FFS File */
    const static UINT8 erasePolarity = 0;
    const static UINT8 revision = 0;
    const static UINT32 size = fileBody.size();

    QUuid uuid = QUuid(guid);
    QByteArray baGuid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));

    printf("GUID: %s\n",qPrintable(uuid.toString()));

    bufFileHdr = QByteArray(size - baGuid.size(), erasePolarity == ERASE_POLARITY_TRUE ? '\xFF' : '\x00');

    bufFileHdr.prepend(baGuid);

    EFI_FFS_FILE_HEADER* fileHeader = (EFI_FFS_FILE_HEADER*)bufFileHdr.data();
    uint32ToUint24(sizeof(EFI_FFS_FILE_HEADER)+size, fileHeader->Size);
    fileHeader->Attributes = 0x00;
    fileHeader->Type = EFI_FV_FILETYPE_FREEFORM;
    fileHeader->State = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;
    // Invert state bits if erase polarity is true
    if (erasePolarity == ERASE_POLARITY_TRUE)
        fileHeader->State = ~fileHeader->State;

    // Calculate header checksum
    fileHeader->IntegrityCheck.Checksum.Header = 0;
    fileHeader->IntegrityCheck.Checksum.File = 0;
    fileHeader->IntegrityCheck.Checksum.Header = calculateChecksum8((UINT8*)fileHeader, sizeof(EFI_FFS_FILE_HEADER)-1);

    // Set data checksum
    if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM)
        fileHeader->IntegrityCheck.Checksum.File = calculateChecksum8((UINT8*)fileBody.constData(), fileBody.size());
    else if (revision == 1)
        fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM;
    else
        fileHeader->IntegrityCheck.Checksum.File = FFS_FIXED_CHECKSUM2;

    out.clear();
    out.append(bufFileHdr, sizeof(EFI_FFS_FILE_HEADER));
    out.append(fileBody);

    return ERR_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objectcontact.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-10-19 12:10:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_OBJECTCONTACT_HXX
#include <svx/sdr/contact/objectcontact.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#include <svx/sdr/contact/viewobjectcontact.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SDR_ANIMATION_OBJECTANIMATOR_HXX
#include <svx/sdr/animation/objectanimator.hxx>
#endif

#ifndef _SDR_EVENT_EVENTHANDLER_HXX
#include <svx/sdr/event/eventhandler.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        ObjectContact::ObjectContact()
        :   mpObjectAnimator(0L),
            mpEventHandler(0L),
            mpViewObjectContactRedirector(0L),
            mbDrawHierarchyValid(sal_False),
            mbIsPreviewRenderer(sal_False)
        {
        }

        // The destructor. When PrepareDelete() was not called before (see there)
        // warnings will be generated in debug version if there are still contacts
        // existing.
        ObjectContact::~ObjectContact()
        {
#ifdef DBG_UTIL
            DBG_ASSERT(0L == maVOCList.Count(),
                "ObjectContact destructor: ViewObjectContactList is not empty, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == mpObjectAnimator,
                "ObjectContact destructor: still an ObjectAnimator existing, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == mpEventHandler,
                "ObjectContact destructor: still an EventHandler existing, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == maDrawHierarchy.Count(),
                "ObjectContact destructor: DrawHierarchyList is not empty, call PrepareDelete() before deleting (!)");
#endif
        }

        // Prepare deletion of this object. Tghis needs to be called always
        // before really deleting this objects. This is necessary since in a c++
        // destructor no virtual function calls are allowed. To avoid this problem,
        // it is required to first call PrepareDelete().
        void ObjectContact::PrepareDelete()
        {
            // #114735# clear DrawHierarchy, empty maDrawHierarchy
            ClearDrawHierarchy();

            // get rid of all registered contacts
            while(maVOCList.Count())
            {
                ViewObjectContact* pCandidate = maVOCList.GetLastObjectAndRemove();
                DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");

                // ViewObjectContacts only make sense with View and Object contacts.
                // When the contact to the SdrObject is deleted like in this case,
                // all ViewObjectContacts can be deleted, too.
                pCandidate->PrepareDelete();
                delete pCandidate;
            }

            // delete the ObjectAnimator. Do that after the members are deleted, since the
            // members will try to deconnect from the local ObjectAnimator.
            DeleteObjectAnimator();

            // delete the EventHandler. This will destroy all still contained events.
            DeleteEventHandler();
        }

        // A new ViewObjectContact was created and shall be remembered.
        void ObjectContact::AddViewObjectContact(ViewObjectContact& rVOContact)
        {
            maVOCList.Append(&rVOContact);
        }

        // A ViewObjectContact was deleted and shall be forgotten.
        void ObjectContact::RemoveViewObjectContact(ViewObjectContact& rVOContact)
        {
            if(maVOCList.Count())
            {
                maVOCList.Remove(&rVOContact);
            }

            // #114735# also remove from base level DrawHierarchy
            if(maDrawHierarchy.Count())
            {
                if(maDrawHierarchy.Remove(&rVOContact))
                {
                    MarkDrawHierarchyInvalid();
                }
            }
        }

        // Test if ViewObjectContact is registered here
        sal_Bool ObjectContact::ContainsViewObjectContact(ViewObjectContact& rVOContact)
        {
            return maVOCList.Contains(&rVOContact);
        }

        // Clear Draw Hierarchy data.
        void ObjectContact::ClearDrawHierarchy()
        {
            // throw away old hierarchy info
            while(maDrawHierarchy.Count())
            {
                ViewObjectContact* pCandidate = maDrawHierarchy.GetLastObjectAndRemove();
                DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");

                pCandidate->ClearDrawHierarchy();
                pCandidate->SetParent(0L);
            }
        }

        // Pre-Process the whole displaying.
        void ObjectContact::PreProcessDisplay(DisplayInfo& rDisplayInfo)
        {
            // The default implementation ensures a valid draw hierarchy.
            EnsureValidDrawHierarchy(rDisplayInfo);
        }

        // test if visualizing of entered groups is switched on at all
        sal_Bool ObjectContact::DoVisualizeEnteredGroup() const
        {
            // Don not do that as default
            return sal_False;
        }

        // Get the active group (the entered group). To get independent
        // from the old object/view classes return values use the new
        // classes.
        ViewContact* ObjectContact::GetActiveGroupContact() const
        {
            // Default has no active group
            return 0L;
        }

        // Get info about validity state of DrawHierarchy
        sal_Bool ObjectContact::IsDrawHierarchyValid() const
        {
            return mbDrawHierarchyValid;
        }

        // Take notice of invalidation of DrawHierarchy from this level. This may
        // be the removal/deletion or insertion of an object. Take preparations for reacting on that.
        void ObjectContact::MarkDrawHierarchyInvalid()
        {
            if(IsDrawHierarchyValid())
            {
                // change flag
                mbDrawHierarchyValid = sal_False;
            }
        }

        // Invalidate given rectangle at the window/output which is represented by
        // this ObjectContact.
        void ObjectContact::InvalidatePartOfView(const Rectangle& rRectangle) const
        {
            // nothing to do here in the default version
        }

        // Non-painted object was changed. Test for potentially
        // getting visible
        void ObjectContact::ObjectGettingPotentiallyVisible(const ViewObjectContact& rVOC) const
        {
            // nothing to do here in the default version
        }

        // #i42815#
        // Get info if given Rectangle is visible in this view
        sal_Bool ObjectContact::IsAreaVisible(const Rectangle& rRectangle) const
        {
            // always visible in default version
            return sal_True;
        }

        // Take some action when new objects are inserted. This is triggered from
        // the VOCs, originating from VCs.
        void ObjectContact::ActionChildInserted(const Rectangle& rInitialRectangle)
        {
            // invalidate initial object proportions to get the Paint started
            InvalidatePartOfView(rInitialRectangle);

            // Mark DrawHierarchy invalid
            MarkDrawHierarchyInvalid();
        }

        // Get info about the need to visualize GluePoints
        sal_Bool ObjectContact::AreGluePointsVisible() const
        {
            return sal_False;
        }

        // method to create a ObjectAnimator. Needs to give a result.
        sdr::animation::ObjectAnimator* ObjectContact::CreateObjectAnimator()
        {
            // Create and return a new ObjectAnimator
            return new sdr::animation::ObjectAnimator();
        }

        // method to create a EventHandler. Needs to give a result.
        sdr::event::TimerEventHandler* ObjectContact::CreateEventHandler()
        {
            // Create and return a new EventHandler
            return new sdr::event::TimerEventHandler();
        }

        // method to get the ObjectAnimator. It will
        // return a existing one or create a new one using CreateObjectAnimator().
        sdr::animation::ObjectAnimator& ObjectContact::GetObjectAnimator() const
        {
            if(!HasObjectAnimator())
            {
                ((ObjectContact*)this)->mpObjectAnimator = ((ObjectContact*)this)->CreateObjectAnimator();
                DBG_ASSERT(mpObjectAnimator,
                    "ObjectContact::GetObjectAnimator(): Got no ObjectAnimator (!)");
            }

            return *mpObjectAnimator;
        }

        // method to get the EventHandler. It will
        // return a existing one or create a new one using CreateEventHandler().
        sdr::event::TimerEventHandler& ObjectContact::GetEventHandler() const
        {
            if(!HasEventHandler())
            {
                ((ObjectContact*)this)->mpEventHandler = ((ObjectContact*)this)->CreateEventHandler();
                DBG_ASSERT(mpEventHandler,
                    "ObjectContact::GetEventHandler(): Got no EventHandler (!)");
            }

            return *mpEventHandler;
        }

        // delete the ObjectAnimator
        void ObjectContact::DeleteObjectAnimator()
        {
            if(mpObjectAnimator)
            {
                // If there are still AnimationStates registered, something has went wrong
                DBG_ASSERT(mpObjectAnimator->Count() == 0,
                    "ObjectContact::DeleteObjectAnimator: Still AnimationStates registered (!)");
                delete mpObjectAnimator;
                mpObjectAnimator = 0L;
            }
        }

        // delete the EventHandler
        void ObjectContact::DeleteEventHandler()
        {
            if(mpEventHandler)
            {
                // If there are still Events registered, something has went wrong
                delete mpEventHandler;
                mpEventHandler = 0L;
            }
        }

        // test if there is an ObjectAnimator without creating one on demand
        sal_Bool ObjectContact::HasObjectAnimator() const
        {
            return (0L != mpObjectAnimator);
        }

        // test if there is an EventHandler without creating one on demand
        sal_Bool ObjectContact::HasEventHandler() const
        {
            return (0L != mpEventHandler);
        }

        // check if text animation is allowed. Default is sal_true.
        sal_Bool ObjectContact::IsTextAnimationAllowed() const
        {
            return sal_True;
        }

        // check if graphic animation is allowed. Default is sal_true.
        sal_Bool ObjectContact::IsGraphicAnimationAllowed() const
        {
            return sal_True;
        }

        // check if asynchronious graphis loading is allowed. Default is sal_False.
        sal_Bool ObjectContact::IsAsynchronGraphicsLoadingAllowed() const
        {
            return sal_False;
        }

        // access to ViewObjectContactRedirector
        ViewObjectContactRedirector* ObjectContact::GetViewObjectContactRedirector() const
        {
            return mpViewObjectContactRedirector;
        }

        void ObjectContact::SetViewObjectContactRedirector(ViewObjectContactRedirector* pNew)
        {
            if(mpViewObjectContactRedirector != pNew)
            {
                mpViewObjectContactRedirector = pNew;
            }
        }

        // check if buffering of MasterPages is allowed. Default is sal_False.
        sal_Bool ObjectContact::IsMasterPageBufferingAllowed() const
        {
            return sal_False;
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<commit_msg>INTEGRATION: CWS warnings01 (1.8.150); FILE MERGED 2006/02/21 16:41:10 aw 1.8.150.1: #i55991# Adaptions to warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objectcontact.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 16:25:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SDR_CONTACT_OBJECTCONTACT_HXX
#include <svx/sdr/contact/objectcontact.hxx>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWOBJECTCONTACT_HXX
#include <svx/sdr/contact/viewobjectcontact.hxx>
#endif

#ifndef _SVDPAGE_HXX
#include <svdpage.hxx>
#endif

#ifndef _SDR_CONTACT_VIEWCONTACT_HXX
#include <svx/sdr/contact/viewcontact.hxx>
#endif

#ifndef _SDR_ANIMATION_OBJECTANIMATOR_HXX
#include <svx/sdr/animation/objectanimator.hxx>
#endif

#ifndef _SDR_EVENT_EVENTHANDLER_HXX
#include <svx/sdr/event/eventhandler.hxx>
#endif

//////////////////////////////////////////////////////////////////////////////

namespace sdr
{
    namespace contact
    {
        ObjectContact::ObjectContact()
        :   mpObjectAnimator(0L),
            mpEventHandler(0L),
            mpViewObjectContactRedirector(0L),
            mbDrawHierarchyValid(sal_False),
            mbIsPreviewRenderer(sal_False)
        {
        }

        // The destructor. When PrepareDelete() was not called before (see there)
        // warnings will be generated in debug version if there are still contacts
        // existing.
        ObjectContact::~ObjectContact()
        {
#ifdef DBG_UTIL
            DBG_ASSERT(0L == maVOCList.Count(),
                "ObjectContact destructor: ViewObjectContactList is not empty, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == mpObjectAnimator,
                "ObjectContact destructor: still an ObjectAnimator existing, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == mpEventHandler,
                "ObjectContact destructor: still an EventHandler existing, call PrepareDelete() before deleting (!)");
            DBG_ASSERT(0L == maDrawHierarchy.Count(),
                "ObjectContact destructor: DrawHierarchyList is not empty, call PrepareDelete() before deleting (!)");
#endif
        }

        // Prepare deletion of this object. Tghis needs to be called always
        // before really deleting this objects. This is necessary since in a c++
        // destructor no virtual function calls are allowed. To avoid this problem,
        // it is required to first call PrepareDelete().
        void ObjectContact::PrepareDelete()
        {
            // #114735# clear DrawHierarchy, empty maDrawHierarchy
            ClearDrawHierarchy();

            // get rid of all registered contacts
            while(maVOCList.Count())
            {
                ViewObjectContact* pCandidate = maVOCList.GetLastObjectAndRemove();
                DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");

                // ViewObjectContacts only make sense with View and Object contacts.
                // When the contact to the SdrObject is deleted like in this case,
                // all ViewObjectContacts can be deleted, too.
                pCandidate->PrepareDelete();
                delete pCandidate;
            }

            // delete the ObjectAnimator. Do that after the members are deleted, since the
            // members will try to deconnect from the local ObjectAnimator.
            DeleteObjectAnimator();

            // delete the EventHandler. This will destroy all still contained events.
            DeleteEventHandler();
        }

        // A new ViewObjectContact was created and shall be remembered.
        void ObjectContact::AddViewObjectContact(ViewObjectContact& rVOContact)
        {
            maVOCList.Append(&rVOContact);
        }

        // A ViewObjectContact was deleted and shall be forgotten.
        void ObjectContact::RemoveViewObjectContact(ViewObjectContact& rVOContact)
        {
            if(maVOCList.Count())
            {
                maVOCList.Remove(&rVOContact);
            }

            // #114735# also remove from base level DrawHierarchy
            if(maDrawHierarchy.Count())
            {
                if(maDrawHierarchy.Remove(&rVOContact))
                {
                    MarkDrawHierarchyInvalid();
                }
            }
        }

        // Test if ViewObjectContact is registered here
        sal_Bool ObjectContact::ContainsViewObjectContact(ViewObjectContact& rVOContact)
        {
            return maVOCList.Contains(&rVOContact);
        }

        // Clear Draw Hierarchy data.
        void ObjectContact::ClearDrawHierarchy()
        {
            // throw away old hierarchy info
            while(maDrawHierarchy.Count())
            {
                ViewObjectContact* pCandidate = maDrawHierarchy.GetLastObjectAndRemove();
                DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");

                pCandidate->ClearDrawHierarchy();
                pCandidate->SetParent(0L);
            }
        }

        // Pre-Process the whole displaying.
        void ObjectContact::PreProcessDisplay(DisplayInfo& rDisplayInfo)
        {
            // The default implementation ensures a valid draw hierarchy.
            EnsureValidDrawHierarchy(rDisplayInfo);
        }

        // test if visualizing of entered groups is switched on at all
        sal_Bool ObjectContact::DoVisualizeEnteredGroup() const
        {
            // Don not do that as default
            return sal_False;
        }

        // Get the active group (the entered group). To get independent
        // from the old object/view classes return values use the new
        // classes.
        ViewContact* ObjectContact::GetActiveGroupContact() const
        {
            // Default has no active group
            return 0L;
        }

        // Get info about validity state of DrawHierarchy
        sal_Bool ObjectContact::IsDrawHierarchyValid() const
        {
            return mbDrawHierarchyValid;
        }

        // Take notice of invalidation of DrawHierarchy from this level. This may
        // be the removal/deletion or insertion of an object. Take preparations for reacting on that.
        void ObjectContact::MarkDrawHierarchyInvalid()
        {
            if(IsDrawHierarchyValid())
            {
                // change flag
                mbDrawHierarchyValid = sal_False;
            }
        }

        // Invalidate given rectangle at the window/output which is represented by
        // this ObjectContact.
        void ObjectContact::InvalidatePartOfView(const Rectangle& /*rRectangle*/) const
        {
            // nothing to do here in the default version
        }

        // Non-painted object was changed. Test for potentially
        // getting visible
        void ObjectContact::ObjectGettingPotentiallyVisible(const ViewObjectContact& /*rVOC*/) const
        {
            // nothing to do here in the default version
        }

        // #i42815#
        // Get info if given Rectangle is visible in this view
        sal_Bool ObjectContact::IsAreaVisible(const Rectangle& /*rRectangle*/) const
        {
            // always visible in default version
            return sal_True;
        }

        // Take some action when new objects are inserted. This is triggered from
        // the VOCs, originating from VCs.
        void ObjectContact::ActionChildInserted(const Rectangle& rInitialRectangle)
        {
            // invalidate initial object proportions to get the Paint started
            InvalidatePartOfView(rInitialRectangle);

            // Mark DrawHierarchy invalid
            MarkDrawHierarchyInvalid();
        }

        // Get info about the need to visualize GluePoints
        sal_Bool ObjectContact::AreGluePointsVisible() const
        {
            return sal_False;
        }

        // method to create a ObjectAnimator. Needs to give a result.
        sdr::animation::ObjectAnimator* ObjectContact::CreateObjectAnimator()
        {
            // Create and return a new ObjectAnimator
            return new sdr::animation::ObjectAnimator();
        }

        // method to create a EventHandler. Needs to give a result.
        sdr::event::TimerEventHandler* ObjectContact::CreateEventHandler()
        {
            // Create and return a new EventHandler
            return new sdr::event::TimerEventHandler();
        }

        // method to get the ObjectAnimator. It will
        // return a existing one or create a new one using CreateObjectAnimator().
        sdr::animation::ObjectAnimator& ObjectContact::GetObjectAnimator() const
        {
            if(!HasObjectAnimator())
            {
                ((ObjectContact*)this)->mpObjectAnimator = ((ObjectContact*)this)->CreateObjectAnimator();
                DBG_ASSERT(mpObjectAnimator,
                    "ObjectContact::GetObjectAnimator(): Got no ObjectAnimator (!)");
            }

            return *mpObjectAnimator;
        }

        // method to get the EventHandler. It will
        // return a existing one or create a new one using CreateEventHandler().
        sdr::event::TimerEventHandler& ObjectContact::GetEventHandler() const
        {
            if(!HasEventHandler())
            {
                ((ObjectContact*)this)->mpEventHandler = ((ObjectContact*)this)->CreateEventHandler();
                DBG_ASSERT(mpEventHandler,
                    "ObjectContact::GetEventHandler(): Got no EventHandler (!)");
            }

            return *mpEventHandler;
        }

        // delete the ObjectAnimator
        void ObjectContact::DeleteObjectAnimator()
        {
            if(mpObjectAnimator)
            {
                // If there are still AnimationStates registered, something has went wrong
                DBG_ASSERT(mpObjectAnimator->Count() == 0,
                    "ObjectContact::DeleteObjectAnimator: Still AnimationStates registered (!)");
                delete mpObjectAnimator;
                mpObjectAnimator = 0L;
            }
        }

        // delete the EventHandler
        void ObjectContact::DeleteEventHandler()
        {
            if(mpEventHandler)
            {
                // If there are still Events registered, something has went wrong
                delete mpEventHandler;
                mpEventHandler = 0L;
            }
        }

        // test if there is an ObjectAnimator without creating one on demand
        sal_Bool ObjectContact::HasObjectAnimator() const
        {
            return (0L != mpObjectAnimator);
        }

        // test if there is an EventHandler without creating one on demand
        sal_Bool ObjectContact::HasEventHandler() const
        {
            return (0L != mpEventHandler);
        }

        // check if text animation is allowed. Default is sal_true.
        sal_Bool ObjectContact::IsTextAnimationAllowed() const
        {
            return sal_True;
        }

        // check if graphic animation is allowed. Default is sal_true.
        sal_Bool ObjectContact::IsGraphicAnimationAllowed() const
        {
            return sal_True;
        }

        // check if asynchronious graphis loading is allowed. Default is sal_False.
        sal_Bool ObjectContact::IsAsynchronGraphicsLoadingAllowed() const
        {
            return sal_False;
        }

        // access to ViewObjectContactRedirector
        ViewObjectContactRedirector* ObjectContact::GetViewObjectContactRedirector() const
        {
            return mpViewObjectContactRedirector;
        }

        void ObjectContact::SetViewObjectContactRedirector(ViewObjectContactRedirector* pNew)
        {
            if(mpViewObjectContactRedirector != pNew)
            {
                mpViewObjectContactRedirector = pNew;
            }
        }

        // check if buffering of MasterPages is allowed. Default is sal_False.
        sal_Bool ObjectContact::IsMasterPageBufferingAllowed() const
        {
            return sal_False;
        }
    } // end of namespace contact
} // end of namespace sdr

//////////////////////////////////////////////////////////////////////////////
// eof
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  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 Willow Garage, Inc. 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.
 *

 * Author: Julius Kammerl (julius@kammerl.de)
 */

#include <pcl/compression/libpng_wrapper.h>

#include <png.h>
#include <zlib.h>

#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>

// user defined I/O callback methods for libPNG
namespace
{
  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
  {
    uint8_t** input_pointer = reinterpret_cast<uint8_t**>(png_get_io_ptr (png_ptr));

    memcpy (data, *input_pointer, sizeof (uint8_t) * length);
    (*input_pointer) += length;
  }

  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_write_data (png_structp png_ptr,  png_bytep data, png_size_t length)
  {
    std::vector<uint8_t>* pngVec = reinterpret_cast<std::vector<uint8_t>*>(png_get_io_ptr (png_ptr));
    std::copy (data, data + length, std::back_inserter (*pngVec));
  }

  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_flush_data (png_structp)
  {
  }
}

namespace pcl
{
  namespace io
  {
    ///////////////////////////////////////////////////////////////////////////////////////////
    template<typename T> void
    encodeImageToPNG (typename std::vector<T>& image_arg,
                      size_t width_arg,
                      size_t height_arg,
                      int image_format_arg,
                      typename std::vector<uint8_t>& pngData_arg,
                      int png_level_arg)
    {
      png_structp png_ptr;
      png_infop info_ptr;
      volatile int channels;

      if (image_arg.size () ==0)
        return;

      // Get amount of channels
      switch (image_format_arg)
       {
         case PNG_COLOR_TYPE_GRAY:
           channels = 1;
           break;
         case PNG_COLOR_TYPE_GRAY_ALPHA:
           channels = 2;
           break;
         case PNG_COLOR_TYPE_RGB:
           channels = 3;
           break;
         case PNG_COLOR_TYPE_RGB_ALPHA:
           channels = 4;
           break;
         default:
           channels = 0;
           break;
       }

      // Ensure valid input array
      assert (image_arg.size () == width_arg*height_arg*channels);

      // Initialize write structure
      png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
      assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");

      // Initialize info structure
      info_ptr = png_create_info_struct (png_ptr);
      assert (info_ptr && "Could not allocate info struct");

      // Setup Exception handling
      assert (setjmp(png_jmpbuf(png_ptr)) && "Error during png compression");

      // reserve memory for output data (300kB)
      pngData_arg.clear ();
      pngData_arg.reserve (300 * 1024);

      // Define I/O methods
      png_set_write_fn (png_ptr, reinterpret_cast<void*> (&pngData_arg),
                        user_write_data, user_flush_data);

      // Define zlib compression level
      if (png_level_arg >= 0)
      {
        png_set_compression_level (png_ptr, png_level_arg);
      }
      else
      {
        png_set_compression_level (png_ptr, Z_DEFAULT_COMPRESSION);
      }

      // Write header
      png_set_IHDR (png_ptr, info_ptr, width_arg, height_arg, sizeof(T) * 8,
          image_format_arg, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
          PNG_FILTER_TYPE_DEFAULT);

      png_write_info (png_ptr, info_ptr);

      // Write image data
      size_t y;
      for (y = 0; y < height_arg; y++)
      {
        png_write_row (png_ptr, reinterpret_cast<png_bytep> (&image_arg[y * width_arg * channels]));
      }

      // End write
      png_write_end (png_ptr, 0);

      if (info_ptr)
        png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
      if (png_ptr)
        png_destroy_write_struct (&png_ptr, 0);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////
    template<typename T> void
    decodePNGImage (typename std::vector<uint8_t>& pngData_arg,
                    typename std::vector<T>& imageData_arg,
                    size_t& width_arg,
                    size_t& height_arg,
                    unsigned int& channels_arg)
    {
      int y;
      png_structp png_ptr;
      png_infop info_ptr;
      png_uint_32 png_width;
      png_uint_32 png_height;
      int png_bit_depth, png_color_type, png_interlace_type;

      png_bytep * row_pointers;

      if (pngData_arg.size () == 0)
        return;

      png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
      assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");

      // Initialize info structure
      info_ptr = png_create_info_struct (png_ptr);
      assert(info_ptr && "Could not allocate info struct");

      // Setup Exception handling
      assert (setjmp (png_jmpbuf(png_ptr)) && "Error during png compression");

      uint8_t* input_pointer = &pngData_arg[0];
      png_set_read_fn (png_ptr, reinterpret_cast<void*> (&input_pointer), user_read_data);

      png_read_info (png_ptr, info_ptr);

      png_get_IHDR (png_ptr, info_ptr, &png_width, &png_height, &png_bit_depth,
          &png_color_type, &png_interlace_type, NULL, NULL);

      // ensure a color bit depth of 8
      assert(png_bit_depth==sizeof(T)*8);

      unsigned int png_channels;
      switch (png_color_type)
      {
        case PNG_COLOR_TYPE_GRAY:
          png_channels = 1;
          break;
        case PNG_COLOR_TYPE_GRAY_ALPHA:
          png_channels = 2;
          break;
        case PNG_COLOR_TYPE_RGB:
          png_channels = 3;
          break;
        case PNG_COLOR_TYPE_RGB_ALPHA:
          png_channels = 4;
          break;
        default:
          png_channels = 0;
          break;
      }

      width_arg = png_width;
      height_arg = png_height;
      channels_arg = png_channels;

      imageData_arg.clear ();
      imageData_arg.resize (png_height * png_width * png_channels);

      row_pointers = reinterpret_cast<png_bytep*> (malloc (sizeof(png_bytep) * png_height));

      for (y = 0; y < png_height; y++)
        row_pointers[y] = reinterpret_cast<png_byte*> (&imageData_arg[y * png_width * png_channels]);

      png_read_image (png_ptr, row_pointers);

      if (info_ptr)
        png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
      if (png_ptr)
        png_destroy_read_struct (&png_ptr, 0, 0);
      if (row_pointers)
        free (row_pointers);
    }
  } // namespace io
} // namespace pcl

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeMonoImageToPNG (std::vector<uint8_t>& image_arg,
                               size_t width_arg,
                               size_t height_arg,
                               std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint8_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeMonoImageToPNG (std::vector<uint16_t>& image_arg,
                               size_t width_arg,
                               size_t height_arg,
                               std::vector<uint8_t>& pngData_arg,
                               int png_level_arg)
{
  encodeImageToPNG<uint16_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeRGBImageToPNG (std::vector<uint8_t>& image_arg,
                              size_t width_arg,
                              size_t height_arg,
                              std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint8_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeRGBImageToPNG (std::vector<uint16_t>& image_arg,
                              size_t width_arg,
                              size_t height_arg,
                              std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint16_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
                           std::vector<uint8_t>& imageData_arg,
                           size_t& width_arg,
                           size_t& height_arg,
                           unsigned int& channels_arg)
{
  decodePNGImage<uint8_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
                           std::vector<uint16_t>& imageData_arg,
                           size_t& width_arg,
                           size_t& height_arg,
                           unsigned int& channels_arg)
{
  decodePNGImage<uint16_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
}

<commit_msg>fixed assert issue in io/src/libpng_wrapper.cpp<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  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 Willow Garage, Inc. 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.
 *

 * Author: Julius Kammerl (julius@kammerl.de)
 */

#include <pcl/compression/libpng_wrapper.h>

#include <png.h>
#include <zlib.h>

#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>

// user defined I/O callback methods for libPNG
namespace
{
  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_read_data (png_structp png_ptr, png_bytep data, png_size_t length)
  {
    uint8_t** input_pointer = reinterpret_cast<uint8_t**>(png_get_io_ptr (png_ptr));

    memcpy (data, *input_pointer, sizeof (uint8_t) * length);
    (*input_pointer) += length;
  }

  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_write_data (png_structp png_ptr,  png_bytep data, png_size_t length)
  {
    std::vector<uint8_t>* pngVec = reinterpret_cast<std::vector<uint8_t>*>(png_get_io_ptr (png_ptr));
    std::copy (data, data + length, std::back_inserter (*pngVec));
  }

  /////////////////////////////////////////////////////////////////////////////////////////
  void
  user_flush_data (png_structp)
  {
  }
}

namespace pcl
{
  namespace io
  {
    ///////////////////////////////////////////////////////////////////////////////////////////
    template<typename T> void
    encodeImageToPNG (typename std::vector<T>& image_arg,
                      size_t width_arg,
                      size_t height_arg,
                      int image_format_arg,
                      typename std::vector<uint8_t>& pngData_arg,
                      int png_level_arg)
    {
      png_structp png_ptr;
      png_infop info_ptr;
      volatile int channels;

      if (image_arg.size () ==0)
        return;

      // Get amount of channels
      switch (image_format_arg)
       {
         case PNG_COLOR_TYPE_GRAY:
           channels = 1;
           break;
         case PNG_COLOR_TYPE_GRAY_ALPHA:
           channels = 2;
           break;
         case PNG_COLOR_TYPE_RGB:
           channels = 3;
           break;
         case PNG_COLOR_TYPE_RGB_ALPHA:
           channels = 4;
           break;
         default:
           channels = 0;
           break;
       }

      // Ensure valid input array
      assert (image_arg.size () == width_arg*height_arg*channels);

      // Initialize write structure
      png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
      assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");

      // Initialize info structure
      info_ptr = png_create_info_struct (png_ptr);
      assert (info_ptr && "Could not allocate info struct");

      // Setup Exception handling
      setjmp(png_jmpbuf(png_ptr));

      // reserve memory for output data (300kB)
      pngData_arg.clear ();
      pngData_arg.reserve (300 * 1024);

      // Define I/O methods
      png_set_write_fn (png_ptr, reinterpret_cast<void*> (&pngData_arg),
                        user_write_data, user_flush_data);

      // Define zlib compression level
      if (png_level_arg >= 0)
      {
        png_set_compression_level (png_ptr, png_level_arg);
      }
      else
      {
        png_set_compression_level (png_ptr, Z_DEFAULT_COMPRESSION);
      }

      // Write header
      png_set_IHDR (png_ptr, info_ptr, width_arg, height_arg, sizeof(T) * 8,
          image_format_arg, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
          PNG_FILTER_TYPE_DEFAULT);

      png_write_info (png_ptr, info_ptr);

      // Write image data
      size_t y;
      for (y = 0; y < height_arg; y++)
      {
        png_write_row (png_ptr, reinterpret_cast<png_bytep> (&image_arg[y * width_arg * channels]));
      }

      // End write
      png_write_end (png_ptr, 0);

      if (info_ptr)
        png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
      if (png_ptr)
        png_destroy_write_struct (&png_ptr, 0);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////
    template<typename T> void
    decodePNGImage (typename std::vector<uint8_t>& pngData_arg,
                    typename std::vector<T>& imageData_arg,
                    size_t& width_arg,
                    size_t& height_arg,
                    unsigned int& channels_arg)
    {
      int y;
      png_structp png_ptr;
      png_infop info_ptr;
      png_uint_32 png_width;
      png_uint_32 png_height;
      int png_bit_depth, png_color_type, png_interlace_type;

      png_bytep * row_pointers;

      if (pngData_arg.size () == 0)
        return;

      png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
      assert (png_ptr && "creating png_create_write_structpng_create_write_struct failed");

      // Initialize info structure
      info_ptr = png_create_info_struct (png_ptr);
      assert(info_ptr && "Could not allocate info struct");

      // Setup Exception handling
      setjmp (png_jmpbuf(png_ptr));

      uint8_t* input_pointer = &pngData_arg[0];
      png_set_read_fn (png_ptr, reinterpret_cast<void*> (&input_pointer), user_read_data);

      png_read_info (png_ptr, info_ptr);

      png_get_IHDR (png_ptr, info_ptr, &png_width, &png_height, &png_bit_depth,
          &png_color_type, &png_interlace_type, NULL, NULL);

      // ensure a color bit depth of 8
      assert(png_bit_depth==sizeof(T)*8);

      unsigned int png_channels;
      switch (png_color_type)
      {
        case PNG_COLOR_TYPE_GRAY:
          png_channels = 1;
          break;
        case PNG_COLOR_TYPE_GRAY_ALPHA:
          png_channels = 2;
          break;
        case PNG_COLOR_TYPE_RGB:
          png_channels = 3;
          break;
        case PNG_COLOR_TYPE_RGB_ALPHA:
          png_channels = 4;
          break;
        default:
          png_channels = 0;
          break;
      }

      width_arg = png_width;
      height_arg = png_height;
      channels_arg = png_channels;

      imageData_arg.clear ();
      imageData_arg.resize (png_height * png_width * png_channels);

      row_pointers = reinterpret_cast<png_bytep*> (malloc (sizeof(png_bytep) * png_height));

      for (y = 0; y < png_height; y++)
        row_pointers[y] = reinterpret_cast<png_byte*> (&imageData_arg[y * png_width * png_channels]);

      png_read_image (png_ptr, row_pointers);

      if (info_ptr)
        png_free_data (png_ptr, info_ptr, PNG_FREE_ALL, -1);
      if (png_ptr)
        png_destroy_read_struct (&png_ptr, 0, 0);
      if (row_pointers)
        free (row_pointers);
    }
  } // namespace io
} // namespace pcl

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeMonoImageToPNG (std::vector<uint8_t>& image_arg,
                               size_t width_arg,
                               size_t height_arg,
                               std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint8_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeMonoImageToPNG (std::vector<uint16_t>& image_arg,
                               size_t width_arg,
                               size_t height_arg,
                               std::vector<uint8_t>& pngData_arg,
                               int png_level_arg)
{
  encodeImageToPNG<uint16_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_GRAY, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeRGBImageToPNG (std::vector<uint8_t>& image_arg,
                              size_t width_arg,
                              size_t height_arg,
                              std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint8_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::encodeRGBImageToPNG (std::vector<uint16_t>& image_arg,
                              size_t width_arg,
                              size_t height_arg,
                              std::vector<uint8_t>& pngData_arg,
                              int png_level_arg)
{
  encodeImageToPNG<uint16_t>(image_arg, width_arg, height_arg, PNG_COLOR_TYPE_RGB, pngData_arg, png_level_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
                           std::vector<uint8_t>& imageData_arg,
                           size_t& width_arg,
                           size_t& height_arg,
                           unsigned int& channels_arg)
{
  decodePNGImage<uint8_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
}

///////////////////////////////////////////////////////////////////////////////////////////
void
pcl::io::decodePNGToImage (std::vector<uint8_t>& pngData_arg,
                           std::vector<uint16_t>& imageData_arg,
                           size_t& width_arg,
                           size_t& height_arg,
                           unsigned int& channels_arg)
{
  decodePNGImage<uint16_t> (pngData_arg, imageData_arg, width_arg, height_arg, channels_arg);
}

<|endoftext|>


<commit_before>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "surface_glue_android.h"

#include <jni.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <unordered_map>

#include <android/input.h>
#include <android/keycodes.h>
#include <android/looper.h>
#include <android/native_window_jni.h>

#include "../Application.h"
#include "SkTypes.h"
#include "SkUtils.h"
#include "Window_android.h"

namespace sk_app {

static const int LOOPER_ID_MESSAGEPIPE = 1;

static const std::unordered_map<int, Window::Key> ANDROID_TO_WINDOW_KEYMAP({
    {AKEYCODE_SOFT_LEFT, Window::Key::kLeft},
    {AKEYCODE_SOFT_RIGHT, Window::Key::kRight}
});

static const std::unordered_map<int, Window::InputState> ANDROID_TO_WINDOW_STATEMAP({
    {AMOTION_EVENT_ACTION_DOWN, Window::kDown_InputState},
    {AMOTION_EVENT_ACTION_POINTER_DOWN, Window::kDown_InputState},
    {AMOTION_EVENT_ACTION_UP, Window::kUp_InputState},
    {AMOTION_EVENT_ACTION_POINTER_UP, Window::kUp_InputState},
    {AMOTION_EVENT_ACTION_MOVE, Window::kMove_InputState},
    {AMOTION_EVENT_ACTION_CANCEL, Window::kUp_InputState},
});

SkiaAndroidApp::SkiaAndroidApp(JNIEnv* env, jobject androidApp) {
    env->GetJavaVM(&fJavaVM);
    fAndroidApp = env->NewGlobalRef(androidApp);
    jclass cls = env->GetObjectClass(fAndroidApp);
    fSetTitleMethodID = env->GetMethodID(cls, "setTitle", "(Ljava/lang/String;)V");
    fNativeWindow = nullptr;
    pthread_create(&fThread, nullptr, pthread_main, this);
}

SkiaAndroidApp::~SkiaAndroidApp() {
    fPThreadEnv->DeleteGlobalRef(fAndroidApp);
    if (fWindow) {
        fWindow->detach();
    }
    if (fNativeWindow) {
        ANativeWindow_release(fNativeWindow);
        fNativeWindow = nullptr;
    }
    if (fApp) {
        delete fApp;
    }
}

void SkiaAndroidApp::setTitle(const char* title) const {
    jstring titleString = fPThreadEnv->NewStringUTF(title);
    fPThreadEnv->CallVoidMethod(fAndroidApp, fSetTitleMethodID, titleString);
    fPThreadEnv->DeleteLocalRef(titleString);
}

void SkiaAndroidApp::paintIfNeeded() {
    if (fNativeWindow && fWindow) {
        fWindow->onPaint();
    }
}

void SkiaAndroidApp::postMessage(const Message& message) const {
    SkAssertResult(write(fPipes[1], &message, sizeof(message)) == sizeof(message));
}

void SkiaAndroidApp::readMessage(Message* message) const {
    SkAssertResult(read(fPipes[0], message, sizeof(Message)) == sizeof(Message));
}

void SkiaAndroidApp::inval() {
    SkAutoMutexAcquire ama(fMutex);
    if (!fIsContentInvalidated) {
        postMessage(Message(kContentInvalidated));
        fIsContentInvalidated = true;
    }
}

int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
    auto skiaAndroidApp = (SkiaAndroidApp*)data;
    Message message;
    skiaAndroidApp->readMessage(&message);
    SkDebugf("message_callback %d", message.fType);
    SkASSERT(message.fType != kUndefined);

    switch (message.fType) {
        case kDestroyApp: {
            delete skiaAndroidApp;
            pthread_exit(nullptr);
            return 0;
        }
        case kContentInvalidated: {
            SkAutoMutexAcquire ama(skiaAndroidApp->fMutex);
            skiaAndroidApp->fIsContentInvalidated = false;
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceCreated: {
            SkASSERT(!skiaAndroidApp->fNativeWindow && message.fNativeWindow);
            skiaAndroidApp->fNativeWindow = message.fNativeWindow;
            auto window_android = (Window_android*)skiaAndroidApp->fWindow;
            window_android->initDisplay(skiaAndroidApp->fNativeWindow);
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceChanged: {
            SkASSERT(message.fNativeWindow == skiaAndroidApp->fNativeWindow &&
                     message.fNativeWindow);
            int width = ANativeWindow_getWidth(skiaAndroidApp->fNativeWindow);
            int height = ANativeWindow_getHeight(skiaAndroidApp->fNativeWindow);
            auto window_android = (Window_android*)skiaAndroidApp->fWindow;
            window_android->setContentRect(0, 0, width, height);
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceDestroyed: {
            if (skiaAndroidApp->fNativeWindow) {
                auto window_android = (Window_android*)skiaAndroidApp->fWindow;
                window_android->onDisplayDestroyed();
                ANativeWindow_release(skiaAndroidApp->fNativeWindow);
                skiaAndroidApp->fNativeWindow = nullptr;
            }
            break;
        }
        case kKeyPressed: {
            auto it = ANDROID_TO_WINDOW_KEYMAP.find(message.fKeycode);
            SkASSERT(it != ANDROID_TO_WINDOW_KEYMAP.end());
            // No modifier is supported so far
            skiaAndroidApp->fWindow->onKey(it->second, Window::kDown_InputState, 0);
            skiaAndroidApp->fWindow->onKey(it->second, Window::kUp_InputState, 0);
            break;
        }
        case kTouched: {
            auto it = ANDROID_TO_WINDOW_STATEMAP.find(message.fTouchState);
            SkASSERT(it != ANDROID_TO_WINDOW_STATEMAP.end());
            skiaAndroidApp->fWindow->onTouch(message.fTouchOwner, it->second, message.fTouchX,
                                             message.fTouchY);
            break;
        }
        default: {
            // do nothing
        }
    }

    return 1;  // continue receiving callbacks
}

void* SkiaAndroidApp::pthread_main(void* arg) {
    SkDebugf("pthread_main begins");

    auto skiaAndroidApp = (SkiaAndroidApp*)arg;

    // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv
    skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr);

    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    pipe(skiaAndroidApp->fPipes);
    ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
                  message_callback, skiaAndroidApp);

    int ident;
    int events;
    struct android_poll_source* source;

    skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp);

    while ((ident = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
        SkDebugf("ALooper_pollAll ident=%d", ident);
    }

    return nullptr;
}

extern "C"  // extern "C" is needed for JNI (although the method itself is in C++)
    JNIEXPORT jlong JNICALL
    Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv* env, jobject application) {
    SkiaAndroidApp* skiaAndroidApp = new SkiaAndroidApp(env, application);
    return (jlong)((size_t)skiaAndroidApp);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerApplication_destroyNativeApp(
    JNIEnv* env, jobject application, jlong handle) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    skiaAndroidApp->postMessage(Message(kDestroyApp));
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceCreated(
    JNIEnv* env, jobject activity, jlong handle, jobject surface) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kSurfaceCreated);
    message.fNativeWindow = ANativeWindow_fromSurface(env, surface);
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceChanged(
    JNIEnv* env, jobject activity, jlong handle, jobject surface) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kSurfaceChanged);
    message.fNativeWindow = ANativeWindow_fromSurface(env, surface);
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceDestroyed(
    JNIEnv* env, jobject activity, jlong handle) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    skiaAndroidApp->postMessage(Message(kSurfaceDestroyed));
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onKeyPressed(JNIEnv* env,
                                                                                jobject activity,
                                                                                jlong handle,
                                                                                jint keycode) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kKeyPressed);
    message.fKeycode = keycode;
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onTouched(
    JNIEnv* env, jobject activity, jlong handle, jint owner, jfloat x, jfloat y, jint state) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kTouched);
    message.fTouchOwner = owner;
    message.fTouchState = state;
    message.fTouchX = x;
    message.fTouchY = y;
    skiaAndroidApp->postMessage(message);
}

}  // namespace sk_app
<commit_msg>Save comparisons for release.<commit_after>/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "surface_glue_android.h"

#include <jni.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <unordered_map>

#include <android/input.h>
#include <android/keycodes.h>
#include <android/looper.h>
#include <android/native_window_jni.h>

#include "../Application.h"
#include "SkTypes.h"
#include "SkUtils.h"
#include "Window_android.h"

namespace sk_app {

static const int LOOPER_ID_MESSAGEPIPE = 1;

static const std::unordered_map<int, Window::Key> ANDROID_TO_WINDOW_KEYMAP({
    {AKEYCODE_SOFT_LEFT, Window::Key::kLeft},
    {AKEYCODE_SOFT_RIGHT, Window::Key::kRight}
});

static const std::unordered_map<int, Window::InputState> ANDROID_TO_WINDOW_STATEMAP({
    {AMOTION_EVENT_ACTION_DOWN, Window::kDown_InputState},
    {AMOTION_EVENT_ACTION_POINTER_DOWN, Window::kDown_InputState},
    {AMOTION_EVENT_ACTION_UP, Window::kUp_InputState},
    {AMOTION_EVENT_ACTION_POINTER_UP, Window::kUp_InputState},
    {AMOTION_EVENT_ACTION_MOVE, Window::kMove_InputState},
    {AMOTION_EVENT_ACTION_CANCEL, Window::kUp_InputState},
});

SkiaAndroidApp::SkiaAndroidApp(JNIEnv* env, jobject androidApp) {
    env->GetJavaVM(&fJavaVM);
    fAndroidApp = env->NewGlobalRef(androidApp);
    jclass cls = env->GetObjectClass(fAndroidApp);
    fSetTitleMethodID = env->GetMethodID(cls, "setTitle", "(Ljava/lang/String;)V");
    fNativeWindow = nullptr;
    pthread_create(&fThread, nullptr, pthread_main, this);
}

SkiaAndroidApp::~SkiaAndroidApp() {
    fPThreadEnv->DeleteGlobalRef(fAndroidApp);
    if (fWindow) {
        fWindow->detach();
    }
    if (fNativeWindow) {
        ANativeWindow_release(fNativeWindow);
        fNativeWindow = nullptr;
    }
    if (fApp) {
        delete fApp;
    }
}

void SkiaAndroidApp::setTitle(const char* title) const {
    jstring titleString = fPThreadEnv->NewStringUTF(title);
    fPThreadEnv->CallVoidMethod(fAndroidApp, fSetTitleMethodID, titleString);
    fPThreadEnv->DeleteLocalRef(titleString);
}

void SkiaAndroidApp::paintIfNeeded() {
    if (fNativeWindow && fWindow) {
        fWindow->onPaint();
    }
}

void SkiaAndroidApp::postMessage(const Message& message) const {
    SkDEBUGCODE(auto writeSize =) write(fPipes[1], &message, sizeof(message));
    SkASSERT(writeSize == sizeof(message));
}

void SkiaAndroidApp::readMessage(Message* message) const {
    SkDEBUGCODE(auto readSize =) read(fPipes[0], message, sizeof(Message));
    SkASSERT(readSize == sizeof(Message));
}

void SkiaAndroidApp::inval() {
    SkAutoMutexAcquire ama(fMutex);
    if (!fIsContentInvalidated) {
        postMessage(Message(kContentInvalidated));
        fIsContentInvalidated = true;
    }
}

int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
    auto skiaAndroidApp = (SkiaAndroidApp*)data;
    Message message;
    skiaAndroidApp->readMessage(&message);
    SkDebugf("message_callback %d", message.fType);
    SkASSERT(message.fType != kUndefined);

    switch (message.fType) {
        case kDestroyApp: {
            delete skiaAndroidApp;
            pthread_exit(nullptr);
            return 0;
        }
        case kContentInvalidated: {
            SkAutoMutexAcquire ama(skiaAndroidApp->fMutex);
            skiaAndroidApp->fIsContentInvalidated = false;
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceCreated: {
            SkASSERT(!skiaAndroidApp->fNativeWindow && message.fNativeWindow);
            skiaAndroidApp->fNativeWindow = message.fNativeWindow;
            auto window_android = (Window_android*)skiaAndroidApp->fWindow;
            window_android->initDisplay(skiaAndroidApp->fNativeWindow);
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceChanged: {
            SkASSERT(message.fNativeWindow == skiaAndroidApp->fNativeWindow &&
                     message.fNativeWindow);
            int width = ANativeWindow_getWidth(skiaAndroidApp->fNativeWindow);
            int height = ANativeWindow_getHeight(skiaAndroidApp->fNativeWindow);
            auto window_android = (Window_android*)skiaAndroidApp->fWindow;
            window_android->setContentRect(0, 0, width, height);
            skiaAndroidApp->paintIfNeeded();
            break;
        }
        case kSurfaceDestroyed: {
            if (skiaAndroidApp->fNativeWindow) {
                auto window_android = (Window_android*)skiaAndroidApp->fWindow;
                window_android->onDisplayDestroyed();
                ANativeWindow_release(skiaAndroidApp->fNativeWindow);
                skiaAndroidApp->fNativeWindow = nullptr;
            }
            break;
        }
        case kKeyPressed: {
            auto it = ANDROID_TO_WINDOW_KEYMAP.find(message.fKeycode);
            SkASSERT(it != ANDROID_TO_WINDOW_KEYMAP.end());
            // No modifier is supported so far
            skiaAndroidApp->fWindow->onKey(it->second, Window::kDown_InputState, 0);
            skiaAndroidApp->fWindow->onKey(it->second, Window::kUp_InputState, 0);
            break;
        }
        case kTouched: {
            auto it = ANDROID_TO_WINDOW_STATEMAP.find(message.fTouchState);
            SkASSERT(it != ANDROID_TO_WINDOW_STATEMAP.end());
            skiaAndroidApp->fWindow->onTouch(message.fTouchOwner, it->second, message.fTouchX,
                                             message.fTouchY);
            break;
        }
        default: {
            // do nothing
        }
    }

    return 1;  // continue receiving callbacks
}

void* SkiaAndroidApp::pthread_main(void* arg) {
    SkDebugf("pthread_main begins");

    auto skiaAndroidApp = (SkiaAndroidApp*)arg;

    // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv
    skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr);

    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    pipe(skiaAndroidApp->fPipes);
    ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
                  message_callback, skiaAndroidApp);

    int ident;
    int events;
    struct android_poll_source* source;

    skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp);

    while ((ident = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
        SkDebugf("ALooper_pollAll ident=%d", ident);
    }

    return nullptr;
}

extern "C"  // extern "C" is needed for JNI (although the method itself is in C++)
    JNIEXPORT jlong JNICALL
    Java_org_skia_viewer_ViewerApplication_createNativeApp(JNIEnv* env, jobject application) {
    SkiaAndroidApp* skiaAndroidApp = new SkiaAndroidApp(env, application);
    return (jlong)((size_t)skiaAndroidApp);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerApplication_destroyNativeApp(
    JNIEnv* env, jobject application, jlong handle) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    skiaAndroidApp->postMessage(Message(kDestroyApp));
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceCreated(
    JNIEnv* env, jobject activity, jlong handle, jobject surface) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kSurfaceCreated);
    message.fNativeWindow = ANativeWindow_fromSurface(env, surface);
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceChanged(
    JNIEnv* env, jobject activity, jlong handle, jobject surface) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kSurfaceChanged);
    message.fNativeWindow = ANativeWindow_fromSurface(env, surface);
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onSurfaceDestroyed(
    JNIEnv* env, jobject activity, jlong handle) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    skiaAndroidApp->postMessage(Message(kSurfaceDestroyed));
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onKeyPressed(JNIEnv* env,
                                                                                jobject activity,
                                                                                jlong handle,
                                                                                jint keycode) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kKeyPressed);
    message.fKeycode = keycode;
    skiaAndroidApp->postMessage(message);
}

extern "C" JNIEXPORT void JNICALL Java_org_skia_viewer_ViewerActivity_onTouched(
    JNIEnv* env, jobject activity, jlong handle, jint owner, jfloat x, jfloat y, jint state) {
    auto skiaAndroidApp = (SkiaAndroidApp*)handle;
    Message message(kTouched);
    message.fTouchOwner = owner;
    message.fTouchState = state;
    message.fTouchX = x;
    message.fTouchY = y;
    skiaAndroidApp->postMessage(message);
}

}  // namespace sk_app
<|endoftext|>