<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

using namespace cv;
using namespace cv::gpu;

namespace
{
    // Compares value to set using the given comparator. Returns true if
    // there is at least one element x in the set satisfying to: x cmp value
    // predicate.
    template <typename Comparer>
    bool compareToSet(const std::string& set_as_str, int value, Comparer cmp)
    {
        if (set_as_str.find_first_not_of(" ") == string::npos)
            return false;

        std::stringstream stream(set_as_str);
        int cur_value;

        while (!stream.eof())
        {
            stream >> cur_value;
            if (cmp(cur_value, value))
                return true;
        }

        return false;
    }
}

CV_EXPORTS bool cv::gpu::TargetArchs::builtWith(cv::gpu::FeatureSet feature_set)
{
    return ::compareToSet(CUDA_ARCH_FEATURES, feature_set, std::greater_equal<int>());
}

CV_EXPORTS bool cv::gpu::TargetArchs::has(int major, int minor)
{
    return hasPtx(major, minor) || hasBin(major, minor);
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasPtx(int major, int minor)
{
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor, std::equal_to<int>());
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasBin(int major, int minor)
{
    return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor, std::equal_to<int>());
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int major, int minor)
{
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor,
                     std::less_equal<int>());
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreater(int major, int minor)
{
    return hasEqualOrGreaterPtx(major, minor) ||
           hasEqualOrGreaterBin(major, minor);
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int major, int minor)
{
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor,
                     std::greater_equal<int>());
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int major, int minor)
{
    return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor,
                     std::greater_equal<int>());
}

#if !defined (HAVE_CUDA)

CV_EXPORTS int cv::gpu::getCudaEnabledDeviceCount() { return 0; }
CV_EXPORTS void cv::gpu::setDevice(int) { throw_nogpu(); }
CV_EXPORTS int cv::gpu::getDevice() { throw_nogpu(); return 0; }
size_t cv::gpu::DeviceInfo::freeMemory() const { throw_nogpu(); return 0; }
size_t cv::gpu::DeviceInfo::totalMemory() const { throw_nogpu(); return 0; }
bool cv::gpu::DeviceInfo::supports(cv::gpu::FeatureSet) const { throw_nogpu(); return false; }
bool cv::gpu::DeviceInfo::isCompatible() const { throw_nogpu(); return false; }
void cv::gpu::DeviceInfo::query() { throw_nogpu(); }
void cv::gpu::DeviceInfo::queryMemory(size_t&, size_t&) const { throw_nogpu(); }

#else /* !defined (HAVE_CUDA) */

CV_EXPORTS int cv::gpu::getCudaEnabledDeviceCount()
{
    int count;
    cudaSafeCall( cudaGetDeviceCount( &count ) );
    return count;
}

CV_EXPORTS void cv::gpu::setDevice(int device)
{
    cudaSafeCall( cudaSetDevice( device ) );
}

CV_EXPORTS int cv::gpu::getDevice()
{
    int device;
    cudaSafeCall( cudaGetDevice( &device ) );
    return device;
}

size_t cv::gpu::DeviceInfo::freeMemory() const
{
    size_t free_memory, total_memory;
    queryMemory(free_memory, total_memory);
    return free_memory;
}

size_t cv::gpu::DeviceInfo::totalMemory() const
{
    size_t free_memory, total_memory;
    queryMemory(free_memory, total_memory);
    return total_memory;
}

bool cv::gpu::DeviceInfo::supports(cv::gpu::FeatureSet feature_set) const
{
    int version = majorVersion() * 10 + minorVersion();
    return version >= feature_set;
}

bool cv::gpu::DeviceInfo::isCompatible() const
{
    // Check PTX compatibility
    if (TargetArchs::hasEqualOrLessPtx(majorVersion(), minorVersion()))
        return true;

    // Check BIN compatibility
    for (int i = minorVersion(); i >= 0; --i)
        if (TargetArchs::hasBin(majorVersion(), i))
            return true;

    return false;
}

void cv::gpu::DeviceInfo::query()
{
    cudaDeviceProp prop;
    cudaSafeCall(cudaGetDeviceProperties(&prop, device_id_));
    name_ = prop.name;
    multi_processor_count_ = prop.multiProcessorCount;
    majorVersion_ = prop.major;
    minorVersion_ = prop.minor;
}

void cv::gpu::DeviceInfo::queryMemory(size_t& free_memory, size_t& total_memory) const
{
    int prev_device_id = getDevice();
    if (prev_device_id != device_id_)
        setDevice(device_id_);

    cudaSafeCall(cudaMemGetInfo(&free_memory, &total_memory));

    if (prev_device_id != device_id_)
        setDevice(prev_device_id);
}

#endif

<commit_msg>Fixed build errors in MSVC when building without CUDA.<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

using namespace cv;
using namespace cv::gpu;

namespace
{
    // Compares value to set using the given comparator. Returns true if
    // there is at least one element x in the set satisfying to: x cmp value
    // predicate.
    template <typename Comparer>
    bool compareToSet(const std::string& set_as_str, int value, Comparer cmp)
    {
        if (set_as_str.find_first_not_of(" ") == string::npos)
            return false;

        std::stringstream stream(set_as_str);
        int cur_value;

        while (!stream.eof())
        {
            stream >> cur_value;
            if (cmp(cur_value, value))
                return true;
        }

        return false;
    }
}

CV_EXPORTS bool cv::gpu::TargetArchs::builtWith(cv::gpu::FeatureSet feature_set)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_FEATURES, feature_set, std::greater_equal<int>());
#else
	return false;
#endif
}

CV_EXPORTS bool cv::gpu::TargetArchs::has(int major, int minor)
{
    return hasPtx(major, minor) || hasBin(major, minor);
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasPtx(int major, int minor)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor, std::equal_to<int>());
#else
	return false;
#endif
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasBin(int major, int minor)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor, std::equal_to<int>());
#else
	return false;
#endif
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrLessPtx(int major, int minor)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor,
                     std::less_equal<int>());
#else
	return false;
#endif
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreater(int major, int minor)
{
    return hasEqualOrGreaterPtx(major, minor) ||
           hasEqualOrGreaterBin(major, minor);
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreaterPtx(int major, int minor)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_PTX, major * 10 + minor,
                     std::greater_equal<int>());
#else
	return false;
#endif
}

CV_EXPORTS bool cv::gpu::TargetArchs::hasEqualOrGreaterBin(int major, int minor)
{
#if defined (HAVE_CUDA)
    return ::compareToSet(CUDA_ARCH_BIN, major * 10 + minor,
                     std::greater_equal<int>());
#else
	return false;
#endif
}

#if !defined (HAVE_CUDA)

CV_EXPORTS int cv::gpu::getCudaEnabledDeviceCount() { return 0; }
CV_EXPORTS void cv::gpu::setDevice(int) { throw_nogpu(); }
CV_EXPORTS int cv::gpu::getDevice() { throw_nogpu(); return 0; }
size_t cv::gpu::DeviceInfo::freeMemory() const { throw_nogpu(); return 0; }
size_t cv::gpu::DeviceInfo::totalMemory() const { throw_nogpu(); return 0; }
bool cv::gpu::DeviceInfo::supports(cv::gpu::FeatureSet) const { throw_nogpu(); return false; }
bool cv::gpu::DeviceInfo::isCompatible() const { throw_nogpu(); return false; }
void cv::gpu::DeviceInfo::query() { throw_nogpu(); }
void cv::gpu::DeviceInfo::queryMemory(size_t&, size_t&) const { throw_nogpu(); }

#else /* !defined (HAVE_CUDA) */

CV_EXPORTS int cv::gpu::getCudaEnabledDeviceCount()
{
    int count;
    cudaSafeCall( cudaGetDeviceCount( &count ) );
    return count;
}

CV_EXPORTS void cv::gpu::setDevice(int device)
{
    cudaSafeCall( cudaSetDevice( device ) );
}

CV_EXPORTS int cv::gpu::getDevice()
{
    int device;
    cudaSafeCall( cudaGetDevice( &device ) );
    return device;
}

size_t cv::gpu::DeviceInfo::freeMemory() const
{
    size_t free_memory, total_memory;
    queryMemory(free_memory, total_memory);
    return free_memory;
}

size_t cv::gpu::DeviceInfo::totalMemory() const
{
    size_t free_memory, total_memory;
    queryMemory(free_memory, total_memory);
    return total_memory;
}

bool cv::gpu::DeviceInfo::supports(cv::gpu::FeatureSet feature_set) const
{
    int version = majorVersion() * 10 + minorVersion();
    return version >= feature_set;
}

bool cv::gpu::DeviceInfo::isCompatible() const
{
    // Check PTX compatibility
    if (TargetArchs::hasEqualOrLessPtx(majorVersion(), minorVersion()))
        return true;

    // Check BIN compatibility
    for (int i = minorVersion(); i >= 0; --i)
        if (TargetArchs::hasBin(majorVersion(), i))
            return true;

    return false;
}

void cv::gpu::DeviceInfo::query()
{
    cudaDeviceProp prop;
    cudaSafeCall(cudaGetDeviceProperties(&prop, device_id_));
    name_ = prop.name;
    multi_processor_count_ = prop.multiProcessorCount;
    majorVersion_ = prop.major;
    minorVersion_ = prop.minor;
}

void cv::gpu::DeviceInfo::queryMemory(size_t& free_memory, size_t& total_memory) const
{
    int prev_device_id = getDevice();
    if (prev_device_id != device_id_)
        setDevice(device_id_);

    cudaSafeCall(cudaMemGetInfo(&free_memory, &total_memory));

    if (prev_device_id != device_id_)
        setDevice(prev_device_id);
}

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: displaying.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:25:44 $
 *
 *  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 AUTODOC_DISPLAYING_HXX
#define AUTODOC_DISPLAYING_HXX

namespace display
{
    class CorporateFrame;
}

namespace autodoc
{

class HtmlDisplay_UdkStd;
class HtmlDisplay_Idl_Ifc;

// class TextDisplay_FunctionList_Ifc;

/** Interface for parsing code of a programming language and
    delivering the information into an Autodoc Repository.
**/
class DisplayToolsFactory_Ifc
{
  public:
    virtual             ~DisplayToolsFactory_Ifc() {}
    static DisplayToolsFactory_Ifc &
                        GetIt_();

//    virtual DYN autodoc::TextDisplay_FunctionList_Ifc *
//                        Create_TextDisplay_FunctionList() const = 0;

    virtual DYN autodoc::HtmlDisplay_UdkStd *
                        Create_HtmlDisplay_UdkStd() const = 0;
    virtual DYN autodoc::HtmlDisplay_Idl_Ifc *
                        Create_HtmlDisplay_Idl() const = 0;

    virtual const display::CorporateFrame &
                        Create_StdFrame() const = 0;
};

} // namespace autodoc

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.80); FILE MERGED 2008/03/28 16:01:30 rt 1.3.80.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: displaying.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef AUTODOC_DISPLAYING_HXX
#define AUTODOC_DISPLAYING_HXX

namespace display
{
    class CorporateFrame;
}

namespace autodoc
{

class HtmlDisplay_UdkStd;
class HtmlDisplay_Idl_Ifc;

// class TextDisplay_FunctionList_Ifc;

/** Interface for parsing code of a programming language and
    delivering the information into an Autodoc Repository.
**/
class DisplayToolsFactory_Ifc
{
  public:
    virtual             ~DisplayToolsFactory_Ifc() {}
    static DisplayToolsFactory_Ifc &
                        GetIt_();

//    virtual DYN autodoc::TextDisplay_FunctionList_Ifc *
//                        Create_TextDisplay_FunctionList() const = 0;

    virtual DYN autodoc::HtmlDisplay_UdkStd *
                        Create_HtmlDisplay_UdkStd() const = 0;
    virtual DYN autodoc::HtmlDisplay_Idl_Ifc *
                        Create_HtmlDisplay_Idl() const = 0;

    virtual const display::CorporateFrame &
                        Create_StdFrame() const = 0;
};

} // namespace autodoc

#endif

<|endoftext|>


<commit_before>/*****************************************************************************
 * dialogs.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "dialogs.hpp"
#include "../commands/async_queue.hpp"
#include "../commands/cmd_change_skin.hpp"
#include "../commands/cmd_quit.hpp"
#include "../commands/cmd_playlist.hpp"
#include "../commands/cmd_playtree.hpp"
#include <vlc_playlist.h>
#include <vlc_modules.h>

/// Callback called when a new skin is chosen
void Dialogs::showChangeSkinCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results )
    {
        if( pArg->psz_results[0] )
        {
            // Create a change skin command
            CmdChangeSkin *pCmd =
                new CmdChangeSkin( pIntf, sFromLocale( pArg->psz_results[0] ) );

            // Push the command in the asynchronous command queue
            AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
            pQueue->push( CmdGenericPtr( pCmd ) );
        }
    }
    else if( !pIntf->p_sys->p_theme )
    {
        // If no theme is already loaded, it's time to quit!
        CmdQuit *pCmd = new CmdQuit( pIntf );
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

void Dialogs::showPlaylistLoadCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results && pArg->psz_results[0] )
    {
        // Create a Playlist Load command
        CmdPlaylistLoad *pCmd =
            new CmdPlaylistLoad( pIntf, sFromLocale( pArg->psz_results[0] ) );

        // Push the command in the asynchronous command queue
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

void Dialogs::showPlaylistSaveCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results && pArg->psz_results[0] )
    {
        // Create a Playlist Save command
        CmdPlaylistSave *pCmd =
            new CmdPlaylistSave( pIntf, pArg->psz_results[0] );

        // Push the command in the asynchronous command queue
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

/// Callback called when the popup menu is requested
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    (void)p_this; (void)psz_variable; (void)old_val;

    Dialogs *p_dialogs = (Dialogs *)param;
    p_dialogs->showPopupMenu( new_val.b_bool != 0, INTF_DIALOG_POPUPMENU );

    return VLC_SUCCESS;
}

Dialogs::Dialogs( intf_thread_t *pIntf ):
    SkinObject( pIntf ), m_pProvider( NULL ), m_pModule( NULL )
{
}

Dialogs::~Dialogs()
{
    if( m_pProvider && m_pModule )
    {
        // Detach the dialogs provider from its parent interface
        module_unneed( m_pProvider, m_pModule );
        vlc_object_release( m_pProvider );

        /* Unregister callbacks */
        var_DelCallback( getIntf()->p_libvlc, "intf-popupmenu",
                         PopupMenuCB, this );
    }
}

Dialogs *Dialogs::instance( intf_thread_t *pIntf )
{
    if( ! pIntf->p_sys->p_dialogs )
    {
        Dialogs *pDialogs = new Dialogs( pIntf );
        if( pDialogs->init() )
        {
            // Initialization succeeded
            pIntf->p_sys->p_dialogs = pDialogs;
        }
        else
        {
            // Initialization failed
            delete pDialogs;
        }
    }
    return pIntf->p_sys->p_dialogs;
}

void Dialogs::destroy( intf_thread_t *pIntf )
{
    delete pIntf->p_sys->p_dialogs;
    pIntf->p_sys->p_dialogs = NULL;
}

bool Dialogs::init()
{
    // Allocate descriptor
    m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(),
                                                    sizeof( intf_thread_t ) );
    if( m_pProvider == NULL )
        return false;

    m_pModule = module_need( m_pProvider, "dialogs provider", NULL, false );
    if( m_pModule == NULL )
    {
        msg_Err( getIntf(), "no suitable dialogs provider found (hint: compile the qt4 plugin, and make sure it is loaded properly)" );
        vlc_object_release( m_pProvider );
        m_pProvider = NULL;
        return false;
    }

    /* Register callback for the intf-popupmenu variable */
    var_AddCallback( getIntf()->p_libvlc, "intf-popupmenu",
                     PopupMenuCB, this );

    return true;
}

void Dialogs::showFileGeneric( const string &rTitle, const string &rExtensions,
                               DlgCallback callback, int flags )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        intf_dialog_args_t *p_arg = (intf_dialog_args_t*)
                                    calloc( 1, sizeof( intf_dialog_args_t ) );

        p_arg->psz_title = strdup( rTitle.c_str() );
        p_arg->psz_extensions = strdup( rExtensions.c_str() );

        p_arg->b_save = flags & kSAVE;
        p_arg->b_multiple = flags & kMULTIPLE;

        p_arg->p_arg = getIntf();
        p_arg->pf_callback = callback;

        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_GENERIC,
                                     0, p_arg );
    }
}

void Dialogs::showChangeSkin()
{
    showFileGeneric( _("Open a skin file"),
                     _("Skin files |*.vlt;*.wsz;*.xml"),
                     showChangeSkinCB, kOPEN );
}

void Dialogs::showPlaylistLoad()
{
    showFileGeneric( _("Open playlist"),
                     _("Playlist Files|"EXTENSIONS_PLAYLIST"|"
                       "All Files|*"),
                     showPlaylistLoadCB, kOPEN );
}

void Dialogs::showPlaylistSave()
{
    showFileGeneric( _("Save playlist"), _("XSPF playlist|*.xspf|"
                                           "M3U file|*.m3u|"
                                           "HTML playlist|*.html"),
                     showPlaylistSaveCB, kSAVE );
}

void Dialogs::showPlaylist()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_PLAYLIST,
                                     0, NULL );
    }
}

void Dialogs::showFileSimple( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_SIMPLE,
                                     (int)play, NULL );
    }
}

void Dialogs::showFile( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE,
                                     (int)play, NULL );
    }
}

void Dialogs::showDirectory( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DIRECTORY,
                                     (int)play, NULL );
    }
}

void Dialogs::showDisc( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DISC,
                                     (int)play, NULL );
    }
}

void Dialogs::showNet( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_NET,
                                     (int)play, NULL );
    }
}

void Dialogs::showMessages()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_MESSAGES, 0, NULL );
    }
}

void Dialogs::showPrefs()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_PREFS, 0, NULL );
    }
}

void Dialogs::showFileInfo()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILEINFO, 0, NULL );
    }
}

void Dialogs::showStreamingWizard()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_WIZARD, 0, NULL );
    }
}

void Dialogs::showPopupMenu( bool bShow, int popupType = INTF_DIALOG_POPUPMENU )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, popupType,
                                     (int)bShow, NULL );
    }
}

void Dialogs::showInteraction( interaction_dialog_t *p_dialog )
{
    intf_dialog_args_t *p_arg = (intf_dialog_args_t *)
                                calloc( 1, sizeof(intf_dialog_args_t) );

    p_arg->p_dialog = p_dialog;
    p_arg->p_intf = getIntf();

    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_INTERACTION,
                                     0, p_arg );
    }
}
<commit_msg>skins2: fix memory leak<commit_after>/*****************************************************************************
 * dialogs.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "dialogs.hpp"
#include "../commands/async_queue.hpp"
#include "../commands/cmd_change_skin.hpp"
#include "../commands/cmd_quit.hpp"
#include "../commands/cmd_playlist.hpp"
#include "../commands/cmd_playtree.hpp"
#include <vlc_playlist.h>
#include <vlc_modules.h>

/// Callback called when a new skin is chosen
void Dialogs::showChangeSkinCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results )
    {
        if( pArg->psz_results[0] )
        {
            // Create a change skin command
            CmdChangeSkin *pCmd =
                new CmdChangeSkin( pIntf, sFromLocale( pArg->psz_results[0] ) );

            // Push the command in the asynchronous command queue
            AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
            pQueue->push( CmdGenericPtr( pCmd ) );
        }
    }
    else if( !pIntf->p_sys->p_theme )
    {
        // If no theme is already loaded, it's time to quit!
        CmdQuit *pCmd = new CmdQuit( pIntf );
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

void Dialogs::showPlaylistLoadCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results && pArg->psz_results[0] )
    {
        // Create a Playlist Load command
        CmdPlaylistLoad *pCmd =
            new CmdPlaylistLoad( pIntf, sFromLocale( pArg->psz_results[0] ) );

        // Push the command in the asynchronous command queue
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

void Dialogs::showPlaylistSaveCB( intf_dialog_args_t *pArg )
{
    intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg;

    if( pArg->i_results && pArg->psz_results[0] )
    {
        // Create a Playlist Save command
        CmdPlaylistSave *pCmd =
            new CmdPlaylistSave( pIntf, pArg->psz_results[0] );

        // Push the command in the asynchronous command queue
        AsyncQueue *pQueue = AsyncQueue::instance( pIntf );
        pQueue->push( CmdGenericPtr( pCmd ) );
    }
}

/// Callback called when the popup menu is requested
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    (void)p_this; (void)psz_variable; (void)old_val;

    Dialogs *p_dialogs = (Dialogs *)param;
    p_dialogs->showPopupMenu( new_val.b_bool != 0, INTF_DIALOG_POPUPMENU );

    return VLC_SUCCESS;
}

Dialogs::Dialogs( intf_thread_t *pIntf ):
    SkinObject( pIntf ), m_pProvider( NULL ), m_pModule( NULL )
{
}

Dialogs::~Dialogs()
{
    if( m_pProvider && m_pModule )
    {
        // Detach the dialogs provider from its parent interface
        module_unneed( m_pProvider, m_pModule );
        vlc_object_release( m_pProvider );

        /* Unregister callbacks */
        var_DelCallback( getIntf()->p_libvlc, "intf-popupmenu",
                         PopupMenuCB, this );
    }
}

Dialogs *Dialogs::instance( intf_thread_t *pIntf )
{
    if( ! pIntf->p_sys->p_dialogs )
    {
        Dialogs *pDialogs = new Dialogs( pIntf );
        if( pDialogs->init() )
        {
            // Initialization succeeded
            pIntf->p_sys->p_dialogs = pDialogs;
        }
        else
        {
            // Initialization failed
            delete pDialogs;
        }
    }
    return pIntf->p_sys->p_dialogs;
}

void Dialogs::destroy( intf_thread_t *pIntf )
{
    delete pIntf->p_sys->p_dialogs;
    pIntf->p_sys->p_dialogs = NULL;
}

bool Dialogs::init()
{
    // Allocate descriptor
    m_pProvider = (intf_thread_t *)vlc_object_create( getIntf(),
                                                    sizeof( intf_thread_t ) );
    if( m_pProvider == NULL )
        return false;

    m_pModule = module_need( m_pProvider, "dialogs provider", NULL, false );
    if( m_pModule == NULL )
    {
        msg_Err( getIntf(), "no suitable dialogs provider found (hint: compile the qt4 plugin, and make sure it is loaded properly)" );
        vlc_object_release( m_pProvider );
        m_pProvider = NULL;
        return false;
    }

    /* Register callback for the intf-popupmenu variable */
    var_AddCallback( getIntf()->p_libvlc, "intf-popupmenu",
                     PopupMenuCB, this );

    return true;
}

void Dialogs::showFileGeneric( const string &rTitle, const string &rExtensions,
                               DlgCallback callback, int flags )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        intf_dialog_args_t *p_arg = (intf_dialog_args_t*)
                                    calloc( 1, sizeof( intf_dialog_args_t ) );

        p_arg->psz_title = strdup( rTitle.c_str() );
        p_arg->psz_extensions = strdup( rExtensions.c_str() );

        p_arg->b_save = flags & kSAVE;
        p_arg->b_multiple = flags & kMULTIPLE;

        p_arg->p_arg = getIntf();
        p_arg->pf_callback = callback;

        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_GENERIC,
                                     0, p_arg );
    }
}

void Dialogs::showChangeSkin()
{
    showFileGeneric( _("Open a skin file"),
                     _("Skin files |*.vlt;*.wsz;*.xml"),
                     showChangeSkinCB, kOPEN );
}

void Dialogs::showPlaylistLoad()
{
    showFileGeneric( _("Open playlist"),
                     _("Playlist Files|"EXTENSIONS_PLAYLIST"|"
                       "All Files|*"),
                     showPlaylistLoadCB, kOPEN );
}

void Dialogs::showPlaylistSave()
{
    showFileGeneric( _("Save playlist"), _("XSPF playlist|*.xspf|"
                                           "M3U file|*.m3u|"
                                           "HTML playlist|*.html"),
                     showPlaylistSaveCB, kSAVE );
}

void Dialogs::showPlaylist()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_PLAYLIST,
                                     0, NULL );
    }
}

void Dialogs::showFileSimple( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE_SIMPLE,
                                     (int)play, NULL );
    }
}

void Dialogs::showFile( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILE,
                                     (int)play, NULL );
    }
}

void Dialogs::showDirectory( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DIRECTORY,
                                     (int)play, NULL );
    }
}

void Dialogs::showDisc( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_DISC,
                                     (int)play, NULL );
    }
}

void Dialogs::showNet( bool play )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_NET,
                                     (int)play, NULL );
    }
}

void Dialogs::showMessages()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_MESSAGES, 0, NULL );
    }
}

void Dialogs::showPrefs()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_PREFS, 0, NULL );
    }
}

void Dialogs::showFileInfo()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_FILEINFO, 0, NULL );
    }
}

void Dialogs::showStreamingWizard()
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_WIZARD, 0, NULL );
    }
}

void Dialogs::showPopupMenu( bool bShow, int popupType = INTF_DIALOG_POPUPMENU )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        m_pProvider->pf_show_dialog( m_pProvider, popupType,
                                     (int)bShow, NULL );
    }
}

void Dialogs::showInteraction( interaction_dialog_t *p_dialog )
{
    if( m_pProvider && m_pProvider->pf_show_dialog )
    {
        intf_dialog_args_t *p_arg = (intf_dialog_args_t *)
                                    calloc( 1, sizeof(intf_dialog_args_t) );

        p_arg->p_dialog = p_dialog;
        p_arg->p_intf = getIntf();

        m_pProvider->pf_show_dialog( m_pProvider, INTF_DIALOG_INTERACTION,
                                     0, p_arg );
    }
}
<|endoftext|>


<commit_before>#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Math.h>
#include <vw/Stereo.h>
#include <vw/Cartography.h>
using namespace vw;
using namespace vw::stereo;
using namespace vw::cartography;

#include "stereo.h"
#include "DEM.h"
#include "nff_terrain.h"
#include "OrthoRasterizer.h"

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

class PointTransFunc : public ReturnFixedType<Vector3> {
  Matrix3x3 m_trans;
public:
  PointTransFunc(Matrix3x3 trans) : m_trans(trans) {}
  Vector3 operator() (Vector3 const& pt) const { return m_trans*pt; }
};

int main( int argc, char *argv[] ) {
  set_debug_level(VerboseDebugMessage+11);

  std::string input_file_name, out_prefix, output_file_type, texture_filename;
  unsigned cache_size, max_triangles;
  float dem_spacing, default_value=0;
  unsigned simplemesh_h_step, simplemesh_v_step;
  int debug_level;
  double semi_major, semi_minor;
  std::string reference_spheroid;
  double phi_rot, omega_rot, kappa_rot;
  std::string rot_order;
  double proj_lat=0, proj_lon=0, proj_scale=1;
  unsigned utm_zone;

  po::options_description desc("Options");
  desc.add_options()
    ("help", "Display this help message")
    ("default-value", po::value<float>(&default_value), "Explicitly set the default (missing pixel) value.  By default, the min z value is used.")
    ("use-alpha", "Create images that have an alpha channel")
    ("dem-spacing,s", po::value<float>(&dem_spacing)->default_value(0), "Set the DEM post size (if this value is 0, the post spacing size is computed for you)")
    ("normalized,n", "Also write a normalized version of the DEM (for debugging)")
    ("orthoimage", po::value<std::string>(&texture_filename), "Write an orthoimage based on the texture file given as an argument to this command line option")
    ("grayscale", "Use grayscale image processing for creating the orthoimage")
    ("offset-files", "Also write a pair of ascii offset files (for debugging)")
    ("cache", po::value<unsigned>(&cache_size)->default_value(1024), "Cache size, in megabytes")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("texture-file", po::value<std::string>(&texture_filename), "Specify texture filename")
    ("output-prefix,o", po::value<std::string>(&out_prefix)->default_value("terrain"), "Specify the output prefix")
    ("output-filetype,t", po::value<std::string>(&output_file_type)->default_value("tif"), "Specify the output file")
    ("debug-level,d", po::value<int>(&debug_level)->default_value(vw::DebugMessage-1), "Set the debugging output level. (0-50+)")
    ("xyz-to-lonlat", "Convert from xyz coordinates to longitude, latitude, altitude coordinates.")
    ("reference-spheroid,r", po::value<std::string>(&reference_spheroid)->default_value(""),"Set a reference surface to a hard coded value (one of [moon , mars].  This will override manually set datum information.")
    ("semi-major-axis", po::value<double>(&semi_major)->default_value(0),"Set the dimensions of the datum.")
    ("semi-minor-axis", po::value<double>(&semi_minor)->default_value(0),"Set the dimensions of the datum.")

    ("sinusoidal", "Save using a sinusoidal projection")
    ("mercator", "Save using a Mercator projection")
    ("transverse-mercator", "Save using a transverse Mercator projection")
    ("orthographic", "Save using an orthographic projection")
    ("stereographic", "Save using a stereographic projection")
    ("lambert-azimuthal", "Save using a Lambert azimuthal projection")
    ("utm", po::value<unsigned>(&utm_zone), "Save using a UTM projection with the given zone")
    ("proj-lat", po::value<double>(&proj_lat), "The center of projection latitude (if applicable)")
    ("proj-lon", po::value<double>(&proj_lon), "The center of projection longitude (if applicable)")
    ("proj-scale", po::value<double>(&proj_scale), "The projection scale (if applicable)")

    ("rotation-order", po::value<std::string>(&rot_order)->default_value("xyz"),"Set the order of an euler angle rotation applied to the 3D points prior to DEM rasterization")
    ("phi-rotation", po::value<double>(&phi_rot)->default_value(0),"Set a rotation angle phi")
    ("omega-rotation", po::value<double>(&omega_rot)->default_value(0),"Set a rotation angle omega")
    ("kappa-rotation", po::value<double>(&kappa_rot)->default_value(0),"Set a rotation angle kappa");

  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  // Set the Vision Workbench debug level
  set_debug_level(debug_level);
  Cache::system_cache().resize( cache_size*1024*1024 );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one pointcloud file and one texture file!" << std::endl;
    std::cout << desc << std::endl;
    return 1;
  }

  DiskImageView<Vector3> point_disk_image(input_file_name);
  ImageViewRef<Vector3> point_image = point_disk_image;

  // Apply an (optional) rotation to the 3D points before building the mesh.
  if (phi_rot != 0 || omega_rot != 0 || kappa_rot != 0) {
    std::cout << "Applying rotation sequence: " << rot_order << "      Angles: " << phi_rot << "   " << omega_rot << "  " << kappa_rot << "\n";
    Matrix3x3 rotation_trans = math::euler_to_rotation_matrix(phi_rot,omega_rot,kappa_rot,rot_order);
    point_image = per_pixel_filter(point_image, PointTransFunc(rotation_trans));
  }

  if (vm.count("xyz-to-lonlat") ) {
    std::cout << "Reprojecting points into longitude, latitude, altitude.\n";
    point_image = cartography::xyz_to_lon_lat_radius(point_image);
  }

  // Select a cartographic DATUM.  There are several hard coded datums
  // that can be used here, or the user can specify their own.
  cartography::Datum datum;
  if ( reference_spheroid != "" ) {
    if (reference_spheroid == "mars") {
      const double MOLA_PEDR_EQUATORIAL_RADIUS = 3396000.0;
      std::cout << "Re-referencing altitude values using standard MOLA spherical radius: " << MOLA_PEDR_EQUATORIAL_RADIUS << "\n";
      datum = cartography::Datum("Mars Datum",
                                 "MOLA PEDR Spheroid",
                                 "Prime Meridian",
                                 MOLA_PEDR_EQUATORIAL_RADIUS,
                                 MOLA_PEDR_EQUATORIAL_RADIUS,
                                 0.0);
    } else if (reference_spheroid == "moon") {
      const double LUNAR_RADIUS = 1737400;
      std::cout << "Re-referencing altitude values using standard lunar spherical radius: " << LUNAR_RADIUS << "\n";
      datum = cartography::Datum("Lunar Datum",
                                 "Lunar Spheroid",
                                 "Prime Meridian",
                                 LUNAR_RADIUS,
                                 LUNAR_RADIUS,
                                 0.0);
    } else {
      std::cout << "Unknown reference spheroid: " << reference_spheroid << ".  Current options are [ moon , mars ]\nExiting.\n\n";
      exit(0);
    }
  } else if (semi_major != 0 && semi_minor != 0) {
    std::cout << "Re-referencing altitude values to user supplied datum.  Semi-major: " << semi_major << "  Semi-minor: " << semi_minor << "\n";
    datum = cartography::Datum("User Specified Datum",
                               "User Specified Spherem",
                               "Prime Meridian",
                               semi_major, semi_minor, 0.0);
  }

  // Set up the georeferencing information.  We specify everything
  // here except for the affine transform, which is defined later once
  // we know the bounds of the orthorasterizer view.  However, we can
  // still reproject the points in the point image without the affine
  // transform because this projection never requires us to convert to
  // or from pixel space.
  GeoReference georef(datum);

  // If the data was left in cartesian coordinates, we need to give
  // the DEM a projection that uses some physical units (meters),
  // rather than lon, lat.  This is actually mainly for compatibility
  // with Viz, and it's sort of a hack, but it's left in for the time
  // being.
  //
  // Otherwise, we honor the user's requested projection and convert
  // the points if necessary.
  if (!vm.count("xyz-to-lonlat"))
    georef.set_mercator(0,0,1);
  else if( vm.count("sinusoidal") ) georef.set_sinusoidal(proj_lon);
  else if( vm.count("mercator") ) georef.set_mercator(proj_lat,proj_lon,proj_scale);
  else if( vm.count("transverse-mercator") ) georef.set_transverse_mercator(proj_lat,proj_lon,proj_scale);
  else if( vm.count("orthographic") ) georef.set_orthographic(proj_lat,proj_lon);
  else if( vm.count("stereographic") ) georef.set_stereographic(proj_lat,proj_lon,proj_scale);
  else if( vm.count("lambert-azimuthal") ) georef.set_lambert_azimuthal(proj_lat,proj_lon);
  else if( vm.count("utm") ) georef.set_UTM( utm_zone );

  if (vm.count("xyz-to-lonlat"))
    point_image = cartography::project_point_image(point_image, georef);

  // Rasterize the results to a temporary file on disk so as to speed
  // up processing in the orthorasterizer, which accesses each pixel
  // multiple times.
  DiskCacheImageView<Vector3> point_image_cache(point_image, "tif");

  // write out the DEM, texture, and extrapolation mask as
  // georeferenced files.
  vw::cartography::OrthoRasterizerView<PixelGray<float> > rasterizer(point_image_cache, select_channel(point_image_cache,2), dem_spacing);
  if (!vm.count("default-value") ) {
    rasterizer.set_use_minz_as_default(true);
  } else {
    rasterizer.set_use_minz_as_default(false);
    rasterizer.set_default_value(default_value);
  }
  if (vm.count("use-alpha")) {
    rasterizer.set_use_alpha(true);
  }

  vw::BBox<float,3> dem_bbox = rasterizer.bounding_box();
  std::cout << "DEM Bounding box: " << dem_bbox << "\n";

  // Now we are ready to specify the affine transform.
  Matrix3x3 georef_affine_transform = rasterizer.geo_transform();
  std::cout << "Georeferencing Transform: " << georef_affine_transform << "\n";
  georef.set_transform(georef_affine_transform);

  // This is a workaround for now to make GDAL write files that don't
  // cause it to crash on read. - mbroxton
  georef.set_datum(Datum());

  // Write out a georeferenced orthoimage of the DTM with alpha.
  if (vm.count("orthoimage")) {
    rasterizer.set_use_minz_as_default(false);
    DiskImageView<PixelGray<float> > texture(texture_filename);
    rasterizer.set_texture(texture);
    BlockCacheView<PixelGray<float> > block_drg_raster(rasterizer, Vector2i(rasterizer.cols(), 2048));
    write_georeferenced_image(out_prefix + "-DRG.tif", channel_cast_rescale<uint8>(block_drg_raster), georef, TerminalProgressCallback() );

  } else {
    // Write out the DEM.
    std::cout << "\n\n Creating block cache view from rasterizer: " << rasterizer.cols() << "  " << rasterizer.rows() << "\n";
    BlockCacheView<PixelGray<float> > block_dem_raster(rasterizer, Vector2i(rasterizer.cols(), 2024));
    write_georeferenced_image(out_prefix + "-DEM." + output_file_type, block_dem_raster, georef, TerminalProgressCallback());

    // Write out a georeferenced DTM and (optionally) a normalized version of the DTM (for debugging)
    if (vm.count("normalized")) {
      DiskImageView<PixelGray<float> > dem_image(out_prefix + "-DEM." + output_file_type);
      write_georeferenced_image(out_prefix + "-DEM-normalized.tif", channel_cast_rescale<uint8>(normalize(dem_image)), georef, TerminalProgressCallback());
    }
  }

  if (vm.count("offset-files")) {
    // Write out the offset files
    std::cout << "Offset: " << dem_bbox.min().x()/rasterizer.spacing() << "   " << dem_bbox.max().y()/rasterizer.spacing() << "\n";
    std::string offset_filename = out_prefix + "-DRG.offset";
    FILE* offset_file = fopen(offset_filename.c_str(), "w");
    fprintf(offset_file, "%d\n%d\n", int(dem_bbox.min().x()/rasterizer.spacing()), -int(dem_bbox.max().y()/rasterizer.spacing()));
    fclose(offset_file);
    offset_filename = out_prefix + "-DEM-normalized.offset";
    offset_file = fopen(offset_filename.c_str(), "w");
    fprintf(offset_file, "%d\n%d\n", int(dem_bbox.min().x()/rasterizer.spacing()), -int(dem_bbox.max().y()/rasterizer.spacing()));
    fclose(offset_file);
  }
  return 0;
}
<commit_msg>Added an option to offset the DEM in the z-axis. <commit_after>#ifdef _MSC_VER
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#endif

#ifdef NDEBUG
#undef NDEBUG
#endif

#include <stdlib.h>

#include <boost/program_options.hpp>
namespace po = boost::program_options;

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Math.h>
#include <vw/Stereo.h>
#include <vw/Cartography.h>
using namespace vw;
using namespace vw::stereo;
using namespace vw::cartography;

#include "stereo.h"
#include "DEM.h"
#include "nff_terrain.h"
#include "OrthoRasterizer.h"

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
}

class PointTransFunc : public ReturnFixedType<Vector3> {
  Matrix3x3 m_trans;
public:
  PointTransFunc(Matrix3x3 trans) : m_trans(trans) {}
  Vector3 operator() (Vector3 const& pt) const { return m_trans*pt; }
};

int main( int argc, char *argv[] ) {
  set_debug_level(VerboseDebugMessage+11);

  std::string input_file_name, out_prefix, output_file_type, texture_filename;
  unsigned cache_size, max_triangles;
  float dem_spacing, default_value=0;
  unsigned simplemesh_h_step, simplemesh_v_step;
  int debug_level;
  double semi_major, semi_minor;
  std::string reference_spheroid;
  double phi_rot, omega_rot, kappa_rot;
  std::string rot_order;
  double proj_lat=0, proj_lon=0, proj_scale=1;
  double z_offset;
  unsigned utm_zone;

  po::options_description desc("Options");
  desc.add_options()
    ("help", "Display this help message")
    ("default-value", po::value<float>(&default_value), "Explicitly set the default (missing pixel) value.  By default, the min z value is used.")
    ("use-alpha", "Create images that have an alpha channel")
    ("dem-spacing,s", po::value<float>(&dem_spacing)->default_value(0), "Set the DEM post size (if this value is 0, the post spacing size is computed for you)")
    ("normalized,n", "Also write a normalized version of the DEM (for debugging)")
    ("orthoimage", po::value<std::string>(&texture_filename), "Write an orthoimage based on the texture file given as an argument to this command line option")
    ("grayscale", "Use grayscale image processing for creating the orthoimage")
    ("offset-files", "Also write a pair of ascii offset files (for debugging)")
    ("cache", po::value<unsigned>(&cache_size)->default_value(1024), "Cache size, in megabytes")
    ("input-file", po::value<std::string>(&input_file_name), "Explicitly specify the input file")
    ("texture-file", po::value<std::string>(&texture_filename), "Specify texture filename")
    ("output-prefix,o", po::value<std::string>(&out_prefix)->default_value("terrain"), "Specify the output prefix")
    ("output-filetype,t", po::value<std::string>(&output_file_type)->default_value("tif"), "Specify the output file")
    ("debug-level,d", po::value<int>(&debug_level)->default_value(vw::DebugMessage-1), "Set the debugging output level. (0-50+)")
    ("xyz-to-lonlat", "Convert from xyz coordinates to longitude, latitude, altitude coordinates.")
    ("reference-spheroid,r", po::value<std::string>(&reference_spheroid)->default_value(""),"Set a reference surface to a hard coded value (one of [moon , mars].  This will override manually set datum information.")
    ("semi-major-axis", po::value<double>(&semi_major)->default_value(0),"Set the dimensions of the datum.")
    ("semi-minor-axis", po::value<double>(&semi_minor)->default_value(0),"Set the dimensions of the datum.")
    ("z-offset", po::value<double>(&z_offset)->default_value(0), "Add a vertical offset to the DEM")

    ("sinusoidal", "Save using a sinusoidal projection")
    ("mercator", "Save using a Mercator projection")
    ("transverse-mercator", "Save using a transverse Mercator projection")
    ("orthographic", "Save using an orthographic projection")
    ("stereographic", "Save using a stereographic projection")
    ("lambert-azimuthal", "Save using a Lambert azimuthal projection")
    ("utm", po::value<unsigned>(&utm_zone), "Save using a UTM projection with the given zone")
    ("proj-lat", po::value<double>(&proj_lat), "The center of projection latitude (if applicable)")
    ("proj-lon", po::value<double>(&proj_lon), "The center of projection longitude (if applicable)")
    ("proj-scale", po::value<double>(&proj_scale), "The projection scale (if applicable)")

    ("rotation-order", po::value<std::string>(&rot_order)->default_value("xyz"),"Set the order of an euler angle rotation applied to the 3D points prior to DEM rasterization")
    ("phi-rotation", po::value<double>(&phi_rot)->default_value(0),"Set a rotation angle phi")
    ("omega-rotation", po::value<double>(&omega_rot)->default_value(0),"Set a rotation angle omega")
    ("kappa-rotation", po::value<double>(&kappa_rot)->default_value(0),"Set a rotation angle kappa");

  po::positional_options_description p;
  p.add("input-file", 1);

  po::variables_map vm;
  po::store( po::command_line_parser( argc, argv ).options(desc).positional(p).run(), vm );
  po::notify( vm );

  // Set the Vision Workbench debug level
  set_debug_level(debug_level);
  Cache::system_cache().resize( cache_size*1024*1024 );

  if( vm.count("help") ) {
    std::cout << desc << std::endl;
    return 1;
  }

  if( vm.count("input-file") != 1 ) {
    std::cout << "Error: Must specify exactly one pointcloud file and one texture file!" << std::endl;
    std::cout << desc << std::endl;
    return 1;
  }

  DiskImageView<Vector3> point_disk_image(input_file_name);
  ImageViewRef<Vector3> point_image = point_disk_image;

  // Apply an (optional) rotation to the 3D points before building the mesh.
  if (phi_rot != 0 || omega_rot != 0 || kappa_rot != 0) {
    std::cout << "Applying rotation sequence: " << rot_order << "      Angles: " << phi_rot << "   " << omega_rot << "  " << kappa_rot << "\n";
    Matrix3x3 rotation_trans = math::euler_to_rotation_matrix(phi_rot,omega_rot,kappa_rot,rot_order);
    point_image = per_pixel_filter(point_image, PointTransFunc(rotation_trans));
  }

  if (vm.count("xyz-to-lonlat") ) {
    std::cout << "Reprojecting points into longitude, latitude, altitude.\n";
    point_image = cartography::xyz_to_lon_lat_radius(point_image);
  }

  // Select a cartographic DATUM.  There are several hard coded datums
  // that can be used here, or the user can specify their own.
  cartography::Datum datum;
  if ( reference_spheroid != "" ) {
    if (reference_spheroid == "mars") {
      const double MOLA_PEDR_EQUATORIAL_RADIUS = 3396000.0;
      std::cout << "Re-referencing altitude values using standard MOLA spherical radius: " << MOLA_PEDR_EQUATORIAL_RADIUS << "\n";
      datum = cartography::Datum("Mars Datum",
                                 "MOLA PEDR Spheroid",
                                 "Prime Meridian",
                                 MOLA_PEDR_EQUATORIAL_RADIUS,
                                 MOLA_PEDR_EQUATORIAL_RADIUS,
                                 0.0);
    } else if (reference_spheroid == "moon") {
      const double LUNAR_RADIUS = 1737400;
      std::cout << "Re-referencing altitude values using standard lunar spherical radius: " << LUNAR_RADIUS << "\n";
      datum = cartography::Datum("Lunar Datum",
                                 "Lunar Spheroid",
                                 "Prime Meridian",
                                 LUNAR_RADIUS,
                                 LUNAR_RADIUS,
                                 0.0);
    } else {
      std::cout << "Unknown reference spheroid: " << reference_spheroid << ".  Current options are [ moon , mars ]\nExiting.\n\n";
      exit(0);
    }
  } else if (semi_major != 0 && semi_minor != 0) {
    std::cout << "Re-referencing altitude values to user supplied datum.  Semi-major: " << semi_major << "  Semi-minor: " << semi_minor << "\n";
    datum = cartography::Datum("User Specified Datum",
                               "User Specified Spherem",
                               "Prime Meridian",
                               semi_major, semi_minor, 0.0);
  }

  // Set up the georeferencing information.  We specify everything
  // here except for the affine transform, which is defined later once
  // we know the bounds of the orthorasterizer view.  However, we can
  // still reproject the points in the point image without the affine
  // transform because this projection never requires us to convert to
  // or from pixel space.
  GeoReference georef(datum);

  // If the data was left in cartesian coordinates, we need to give
  // the DEM a projection that uses some physical units (meters),
  // rather than lon, lat.  This is actually mainly for compatibility
  // with Viz, and it's sort of a hack, but it's left in for the time
  // being.
  //
  // Otherwise, we honor the user's requested projection and convert
  // the points if necessary.
  if (!vm.count("xyz-to-lonlat"))
    georef.set_mercator(0,0,1);
  else if( vm.count("sinusoidal") ) georef.set_sinusoidal(proj_lon);
  else if( vm.count("mercator") ) georef.set_mercator(proj_lat,proj_lon,proj_scale);
  else if( vm.count("transverse-mercator") ) georef.set_transverse_mercator(proj_lat,proj_lon,proj_scale);
  else if( vm.count("orthographic") ) georef.set_orthographic(proj_lat,proj_lon);
  else if( vm.count("stereographic") ) georef.set_stereographic(proj_lat,proj_lon,proj_scale);
  else if( vm.count("lambert-azimuthal") ) georef.set_lambert_azimuthal(proj_lat,proj_lon);
  else if( vm.count("utm") ) georef.set_UTM( utm_zone );

  if (vm.count("xyz-to-lonlat"))
    point_image = cartography::project_point_image(point_image, georef);

  // Rasterize the results to a temporary file on disk so as to speed
  // up processing in the orthorasterizer, which accesses each pixel
  // multiple times.
  DiskCacheImageView<Vector3> point_image_cache(point_image, "tif");

  // write out the DEM, texture, and extrapolation mask as
  // georeferenced files.
  vw::cartography::OrthoRasterizerView<PixelGray<float> > rasterizer(point_image_cache, select_channel(point_image_cache,2), dem_spacing);
  if (!vm.count("default-value") ) {
    rasterizer.set_use_minz_as_default(true);
  } else {
    rasterizer.set_use_minz_as_default(false);
    rasterizer.set_default_value(default_value);
  }
  if (vm.count("use-alpha")) {
    rasterizer.set_use_alpha(true);
  }

  vw::BBox<float,3> dem_bbox = rasterizer.bounding_box();
  std::cout << "DEM Bounding box: " << dem_bbox << "\n";

  // Now we are ready to specify the affine transform.
  Matrix3x3 georef_affine_transform = rasterizer.geo_transform();
  std::cout << "Georeferencing Transform: " << georef_affine_transform << "\n";
  georef.set_transform(georef_affine_transform);

  // This is a workaround for now to make GDAL write files that don't
  // cause it to crash on read. - mbroxton
  georef.set_datum(Datum());

  // Write out a georeferenced orthoimage of the DTM with alpha.
  if (vm.count("orthoimage")) {
    rasterizer.set_use_minz_as_default(false);
    DiskImageView<PixelGray<float> > texture(texture_filename);
    rasterizer.set_texture(texture);
    BlockCacheView<PixelGray<float> > block_drg_raster(rasterizer, Vector2i(rasterizer.cols(), 2048));
    write_georeferenced_image(out_prefix + "-DRG.tif", channel_cast_rescale<uint8>(block_drg_raster), georef, TerminalProgressCallback() );

  } else {
    // Write out the DEM.
    std::cout << "\n\n Creating block cache view from rasterizer: " << rasterizer.cols() << "  " << rasterizer.rows() << "\n";
    BlockCacheView<PixelGray<float> > block_dem_raster(rasterizer, Vector2i(rasterizer.cols(), 2024));
    if (vm.count("z-offset"))
      write_georeferenced_image(out_prefix + "-DEM." + output_file_type, block_dem_raster + z_offset, georef, TerminalProgressCallback());
    else
      write_georeferenced_image(out_prefix + "-DEM." + output_file_type, block_dem_raster, georef, TerminalProgressCallback());

    // Write out a georeferenced DTM and (optionally) a normalized version of the DTM (for debugging)
    if (vm.count("normalized")) {
      DiskImageView<PixelGray<float> > dem_image(out_prefix + "-DEM." + output_file_type);
      write_georeferenced_image(out_prefix + "-DEM-normalized.tif", channel_cast_rescale<uint8>(normalize(dem_image)), georef, TerminalProgressCallback());
    }
  }

  if (vm.count("offset-files")) {
    // Write out the offset files
    std::cout << "Offset: " << dem_bbox.min().x()/rasterizer.spacing() << "   " << dem_bbox.max().y()/rasterizer.spacing() << "\n";
    std::string offset_filename = out_prefix + "-DRG.offset";
    FILE* offset_file = fopen(offset_filename.c_str(), "w");
    fprintf(offset_file, "%d\n%d\n", int(dem_bbox.min().x()/rasterizer.spacing()), -int(dem_bbox.max().y()/rasterizer.spacing()));
    fclose(offset_file);
    offset_filename = out_prefix + "-DEM-normalized.offset";
    offset_file = fopen(offset_filename.c_str(), "w");
    fprintf(offset_file, "%d\n%d\n", int(dem_bbox.min().x()/rasterizer.spacing()), -int(dem_bbox.max().y()/rasterizer.spacing()));
    fclose(offset_file);
  }
  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/edk/system/channel_manager.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"

namespace mojo {
namespace system {

namespace {

void ShutdownChannelHelper(const ChannelInfo& channel_info) {
  if (base::MessageLoopProxy::current() ==
      channel_info.channel_thread_task_runner) {
    channel_info.channel->Shutdown();
  } else {
    channel_info.channel->WillShutdownSoon();
    channel_info.channel_thread_task_runner->PostTask(
        FROM_HERE, base::Bind(&Channel::Shutdown, channel_info.channel));
  }
}

}  // namespace

ChannelManager::ChannelManager() {
}

ChannelManager::~ChannelManager() {
  // No need to take the lock.
  for (const auto& map_elem : channel_infos_)
    ShutdownChannelHelper(map_elem.second);
}

ChannelId ChannelManager::AddChannel(
    scoped_refptr<Channel> channel,
    scoped_refptr<base::TaskRunner> channel_thread_task_runner) {
  ChannelId channel_id = GetChannelId(channel.get());

  {
    base::AutoLock locker(lock_);
    DCHECK(channel_infos_.find(channel_id) == channel_infos_.end());
    channel_infos_[channel_id] =
        ChannelInfo(channel, channel_thread_task_runner);
  }
  channel->SetChannelManager(this);

  return channel_id;
}

void ChannelManager::WillShutdownChannel(ChannelId channel_id) {
  GetChannelInfo(channel_id).channel->WillShutdownSoon();
}

void ChannelManager::ShutdownChannel(ChannelId channel_id) {
  ShutdownChannelHelper(GetChannelInfo(channel_id));
}

ChannelInfo ChannelManager::GetChannelInfo(ChannelId channel_id) {
  ChannelInfo rv;
  base::AutoLock locker(lock_);
  auto it = channel_infos_.find(channel_id);
  DCHECK(it != channel_infos_.end());
  rv.Swap(&it->second);
  channel_infos_.erase(it);
  return rv;
}

}  // namespace system
}  // namespace mojo
<commit_msg>Fix mojo::system::ChannelManager::GetChannelInfo(), hence WillShutdownChannel().<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/edk/system/channel_manager.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"

namespace mojo {
namespace system {

namespace {

void ShutdownChannelHelper(const ChannelInfo& channel_info) {
  if (base::MessageLoopProxy::current() ==
      channel_info.channel_thread_task_runner) {
    channel_info.channel->Shutdown();
  } else {
    channel_info.channel->WillShutdownSoon();
    channel_info.channel_thread_task_runner->PostTask(
        FROM_HERE, base::Bind(&Channel::Shutdown, channel_info.channel));
  }
}

}  // namespace

ChannelManager::ChannelManager() {
}

ChannelManager::~ChannelManager() {
  // No need to take the lock.
  for (const auto& map_elem : channel_infos_)
    ShutdownChannelHelper(map_elem.second);
}

ChannelId ChannelManager::AddChannel(
    scoped_refptr<Channel> channel,
    scoped_refptr<base::TaskRunner> channel_thread_task_runner) {
  ChannelId channel_id = GetChannelId(channel.get());

  {
    base::AutoLock locker(lock_);
    DCHECK(channel_infos_.find(channel_id) == channel_infos_.end());
    channel_infos_[channel_id] =
        ChannelInfo(channel, channel_thread_task_runner);
  }
  channel->SetChannelManager(this);

  return channel_id;
}

void ChannelManager::WillShutdownChannel(ChannelId channel_id) {
  GetChannelInfo(channel_id).channel->WillShutdownSoon();
}

void ChannelManager::ShutdownChannel(ChannelId channel_id) {
  ChannelInfo channel_info;
  {
    base::AutoLock locker(lock_);
    auto it = channel_infos_.find(channel_id);
    DCHECK(it != channel_infos_.end());
    channel_info.Swap(&it->second);
    channel_infos_.erase(it);
  }
  ShutdownChannelHelper(channel_info);
}

ChannelInfo ChannelManager::GetChannelInfo(ChannelId channel_id) {
  base::AutoLock locker(lock_);
  auto it = channel_infos_.find(channel_id);
  DCHECK(it != channel_infos_.end());
  return it->second;
}

}  // namespace system
}  // namespace mojo
<|endoftext|>


<commit_before>/** \file    expand_DIN_ISO_3166_geographic_codes.cc
 *  \author  Dr Johannes Ruscheinski
 *
 *  Converts codes stored in MARC field 044 and generates geographic fully-spelled-out
 *  keyword chains in MARC field GEO
 */

/*
    Copyright (C) 2020, Library of the University of Tübingen

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU 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 <unordered_map>
#include <cstdlib>
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "UBTools.h"
#include "util.h"

namespace {

constexpr char KEYWORD_SEPARATOR('/');

void InitialiseCodesToKeywordChainsMap(std::unordered_map<std::string, std::string> * const codes_to_keyword_chains_map) {
    const auto MAP_FILENAME(UBTools::GetTuelibPath() + "DIN_ISO_3166_geographic_codes_in_German");
    std::unordered_map<std::string, std::string> codes_to_keywords_map;
    unsigned line_no(0);
    for (auto line : FileUtil::ReadLines(MAP_FILENAME)) {
        ++line_no;
        if (unlikely(line.empty()))
            continue;

        const auto FIRST_PIPE_POS(line.find('|'));
        auto keyword(line.substr(0, FIRST_PIPE_POS));
        const auto codes(line.substr(FIRST_PIPE_POS + 1));
        if (unlikely(keyword.empty() or codes.empty()))
            LOG_ERROR("malformed line #" + std::to_string(line_no) + " in \"" + MAP_FILENAME + "\"!");

        codes_to_keywords_map[codes] = StringUtil::Map(&keyword, KEYWORD_SEPARATOR, ';'); // The mapping is probably unnecessary.
    }
    LOG_INFO("Extracted " + std::to_string(codes_to_keywords_map.size()) + " mappings from \"" + MAP_FILENAME + "\".");

    unsigned level(0);
    while (codes_to_keyword_chains_map->size() < codes_to_keywords_map.size()) {
        for (const auto &[codes, keyword] : codes_to_keywords_map) {
            if (StringUtil::CharCount(codes, '-') != level)
                continue;

            if (level == 0)
                (*codes_to_keyword_chains_map)[codes] = keyword;
            else {
                const auto LAST_DASH_POS(codes.rfind('-'));
                const auto code_prefix(codes.substr(0, LAST_DASH_POS));
                const auto code_and_keyword_prefix(codes_to_keyword_chains_map->find(code_prefix));
                if (unlikely(code_and_keyword_prefix == codes_to_keyword_chains_map->end()))
                    LOG_ERROR("code prefix \"" + code_prefix + "\" needed for \"" + codes + "\" is missing!");
                (*codes_to_keyword_chains_map)[codes] = code_and_keyword_prefix->second + std::string(1, KEYWORD_SEPARATOR) + keyword;
            }
        }
        ++level;
    }
}

std::string ExtractSubfield(const std::string &line, const size_t subfield_contents_start_pos) {
    const auto next_dollar_pos(line.find('$', subfield_contents_start_pos));
    if (next_dollar_pos == std::string::npos)
        return line.substr(subfield_contents_start_pos);
    return line.substr(subfield_contents_start_pos, next_dollar_pos - subfield_contents_start_pos);
}

constexpr char MARC_SUBFIELD_SEPARATOR('\x1F');

void InitialiseLocationTo689ContentsMap(std::unordered_map<std::string, std::string> * const locations_to_689_contents_map) {
    const auto FIELD_CONTENTS_FILENAME(UBTools::GetTuelibPath() + "geographic_689_field_contents");

    unsigned line_no(0);
    for (auto line : FileUtil::ReadLines(FIELD_CONTENTS_FILENAME)) {
        ++line_no;
        if (unlikely(line.empty()))
            continue;

        // Primary location
        const auto dollar_a_pos(line.find("$a"));
        if (unlikely(dollar_a_pos == std::string::npos))
            continue;
        std::string location(ExtractSubfield(line, dollar_a_pos + 2));
        if (unlikely(location == "Deutsches Reich"))
            location = "Deutschland <Deutsches Reich>";
        else if (unlikely(location == "Trentino-Südtirol"))
            location = "Italien (Südtirol-Trentino s.dort)";
        else if (unlikely(StringUtil::StartsWith(location, "Kanton ")))
            location = location.substr(__builtin_strlen("Kanton ")) + " <Kanton>";
        else {
            // Optional secondary location
            const auto dollar_g_pos(line.find("$g", dollar_a_pos + 2));
            if (dollar_g_pos != std::string::npos)
                location += " <" + ExtractSubfield(line, dollar_g_pos + 2) + ">";
        }

        if (unlikely(location == "Südafrika"))
            location = "Südafrika <Staat>";
        else if (unlikely(location == "Österreich"))
            (*locations_to_689_contents_map)["Österreich (-12.11.1918)"] = StringUtil::Map(&line, '$', MARC_SUBFIELD_SEPARATOR);
        else if (unlikely(location == "Föderative Republik Jugoslawien"))
            location = "Jugoslawien <Föderative Republik> <Jugoslawien>";
        else if (unlikely(location == "El Salvador"))
            location = "ElSalvador";
        else if (unlikely(location == "Demokratische Republik Kongo"))
            location = "Kongo <Republik>";

        (*locations_to_689_contents_map)[location] = StringUtil::Map(&line, '$', MARC_SUBFIELD_SEPARATOR);
    }

    LOG_INFO("Loaded " + std::to_string(locations_to_689_contents_map->size()) + " mappings from location names to 689 field contents.");
}

// Given "Europa/Deutschland/Baden-Württemberg" this would return "Baden-Württemberg".
std::string GetMostSpecificGeographicLocation(const std::string &geo_keyword_chain) {
    const auto last_keyword_separator_pos(geo_keyword_chain.rfind(KEYWORD_SEPARATOR));
    if (last_keyword_separator_pos == std::string::npos) // Not a chain, but an individual keyword!
        return geo_keyword_chain;
    return geo_keyword_chain.substr(last_keyword_separator_pos + 1);
}

std::string &NormaliseLocation(std::string * const location) {
    const auto comma_space_pos(location->find(", "));
    if (comma_space_pos != std::string::npos) {
        const auto auxillary_location(location->substr(comma_space_pos + 2));
        location->resize(comma_space_pos);
        *location += " <";
        *location += auxillary_location;
        *location += '>';
    }

    return *location;
}

void GenerateExpandedGeographicCodes(MARC::Reader * const reader, MARC::Writer * writer,
                                     const std::unordered_map<std::string, std::string> &codes_to_keyword_chains_map,
                                     const std::unordered_map<std::string, std::string> &locations_to_689_contents_map)
{
    unsigned total_count(0), conversion_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        const auto _044_field(record.findTag("044"));
        if (_044_field == record.end()) {
            writer->write(record);
            continue;
        }

        const auto codes(_044_field->getFirstSubfieldWithCode('c'));
        if (codes.empty()) {
            writer->write(record);
            continue;
        }

        const auto codes_and_keyword_chain(codes_to_keyword_chains_map.find(codes));
        if (unlikely(codes_and_keyword_chain == codes_to_keyword_chains_map.cend()))
            LOG_WARNING("record w/ PPN " + record.getControlNumber() + " contains missing code \""
                        + codes + "\" in 044$c!");
        else {
            auto most_specific_location(GetMostSpecificGeographicLocation(codes_and_keyword_chain->second));
            NormaliseLocation(&most_specific_location);
            const auto most_specific_location_and_689_contents(locations_to_689_contents_map.find(most_specific_location));
            if (unlikely(most_specific_location_and_689_contents == locations_to_689_contents_map.cend()))
                LOG_WARNING("did not find \"" + most_specific_location + "\" in the locations to 689-contents map!");
            else
                record.insertField("689", most_specific_location_and_689_contents->second);

            record.insertField("GEO", 'a', codes_and_keyword_chain->second);
            ++conversion_count;
        }

        writer->write(record);
    }

    LOG_INFO("Processed " + std::to_string(total_count) + " record(s) and converted "
             + std::to_string(conversion_count) + " codes to keyword chains.");
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 3)
        ::Usage("marc_input marc_output");

    std::unordered_map<std::string, std::string> codes_to_keyword_chains_map;
    InitialiseCodesToKeywordChainsMap(&codes_to_keyword_chains_map);

    std::unordered_map<std::string, std::string> locations_to_689_contents_map;
    InitialiseLocationTo689ContentsMap(&locations_to_689_contents_map);

    const auto marc_reader(MARC::Reader::Factory(argv[1]));
    const auto marc_writer(MARC::Writer::Factory(argv[2]));
    GenerateExpandedGeographicCodes(marc_reader.get(), marc_writer.get(), codes_to_keyword_chains_map,
                                    locations_to_689_contents_map);

    return EXIT_SUCCESS;
}
<commit_msg>We now avoid adding already existing geographic keywords.<commit_after>/** \file    expand_DIN_ISO_3166_geographic_codes.cc
 *  \author  Dr Johannes Ruscheinski
 *
 *  Converts codes stored in MARC field 044 and generates geographic fully-spelled-out
 *  keyword chains in MARC field GEO
 */

/*
    Copyright (C) 2020, Library of the University of Tübingen

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU 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 <unordered_map>
#include <cstdlib>
#include "FileUtil.h"
#include "MARC.h"
#include "StringUtil.h"
#include "UBTools.h"
#include "util.h"

namespace {

constexpr char KEYWORD_SEPARATOR('/');

void InitialiseCodesToKeywordChainsMap(std::unordered_map<std::string, std::string> * const codes_to_keyword_chains_map) {
    const auto MAP_FILENAME(UBTools::GetTuelibPath() + "DIN_ISO_3166_geographic_codes_in_German");
    std::unordered_map<std::string, std::string> codes_to_keywords_map;
    unsigned line_no(0);
    for (auto line : FileUtil::ReadLines(MAP_FILENAME)) {
        ++line_no;
        if (unlikely(line.empty()))
            continue;

        const auto FIRST_PIPE_POS(line.find('|'));
        auto keyword(line.substr(0, FIRST_PIPE_POS));
        const auto codes(line.substr(FIRST_PIPE_POS + 1));
        if (unlikely(keyword.empty() or codes.empty()))
            LOG_ERROR("malformed line #" + std::to_string(line_no) + " in \"" + MAP_FILENAME + "\"!");

        codes_to_keywords_map[codes] = StringUtil::Map(&keyword, KEYWORD_SEPARATOR, ';'); // The mapping is probably unnecessary.
    }
    LOG_INFO("Extracted " + std::to_string(codes_to_keywords_map.size()) + " mappings from \"" + MAP_FILENAME + "\".");

    unsigned level(0);
    while (codes_to_keyword_chains_map->size() < codes_to_keywords_map.size()) {
        for (const auto &[codes, keyword] : codes_to_keywords_map) {
            if (StringUtil::CharCount(codes, '-') != level)
                continue;

            if (level == 0)
                (*codes_to_keyword_chains_map)[codes] = keyword;
            else {
                const auto LAST_DASH_POS(codes.rfind('-'));
                const auto code_prefix(codes.substr(0, LAST_DASH_POS));
                const auto code_and_keyword_prefix(codes_to_keyword_chains_map->find(code_prefix));
                if (unlikely(code_and_keyword_prefix == codes_to_keyword_chains_map->end()))
                    LOG_ERROR("code prefix \"" + code_prefix + "\" needed for \"" + codes + "\" is missing!");
                (*codes_to_keyword_chains_map)[codes] = code_and_keyword_prefix->second + std::string(1, KEYWORD_SEPARATOR) + keyword;
            }
        }
        ++level;
    }
}

std::string ExtractSubfield(const std::string &line, const size_t subfield_contents_start_pos) {
    const auto next_dollar_pos(line.find('$', subfield_contents_start_pos));
    if (next_dollar_pos == std::string::npos)
        return line.substr(subfield_contents_start_pos);
    return line.substr(subfield_contents_start_pos, next_dollar_pos - subfield_contents_start_pos);
}

constexpr char MARC_SUBFIELD_SEPARATOR('\x1F');

void InitialiseLocationTo689ContentsMap(std::unordered_map<std::string, std::string> * const locations_to_689_contents_map) {
    const auto FIELD_CONTENTS_FILENAME(UBTools::GetTuelibPath() + "geographic_689_field_contents");

    unsigned line_no(0);
    for (auto line : FileUtil::ReadLines(FIELD_CONTENTS_FILENAME)) {
        ++line_no;
        if (unlikely(line.empty()))
            continue;

        // Primary location
        const auto dollar_a_pos(line.find("$a"));
        if (unlikely(dollar_a_pos == std::string::npos))
            continue;
        std::string location(ExtractSubfield(line, dollar_a_pos + 2));
        if (unlikely(location == "Deutsches Reich"))
            location = "Deutschland <Deutsches Reich>";
        else if (unlikely(location == "Trentino-Südtirol"))
            location = "Italien (Südtirol-Trentino s.dort)";
        else if (unlikely(StringUtil::StartsWith(location, "Kanton ")))
            location = location.substr(__builtin_strlen("Kanton ")) + " <Kanton>";
        else {
            // Optional secondary location
            const auto dollar_g_pos(line.find("$g", dollar_a_pos + 2));
            if (dollar_g_pos != std::string::npos)
                location += " <" + ExtractSubfield(line, dollar_g_pos + 2) + ">";
        }

        if (unlikely(location == "Südafrika"))
            location = "Südafrika <Staat>";
        else if (unlikely(location == "Österreich"))
            (*locations_to_689_contents_map)["Österreich (-12.11.1918)"] = StringUtil::Map(&line, '$', MARC_SUBFIELD_SEPARATOR);
        else if (unlikely(location == "Föderative Republik Jugoslawien"))
            location = "Jugoslawien <Föderative Republik> <Jugoslawien>";
        else if (unlikely(location == "El Salvador"))
            location = "ElSalvador";
        else if (unlikely(location == "Demokratische Republik Kongo"))
            location = "Kongo <Republik>";

        (*locations_to_689_contents_map)[location] = StringUtil::Map(&line, '$', MARC_SUBFIELD_SEPARATOR);
    }

    LOG_INFO("Loaded " + std::to_string(locations_to_689_contents_map->size()) + " mappings from location names to 689 field contents.");
}

// Given "Europa/Deutschland/Baden-Württemberg" this would return "Baden-Württemberg".
std::string GetMostSpecificGeographicLocation(const std::string &geo_keyword_chain) {
    const auto last_keyword_separator_pos(geo_keyword_chain.rfind(KEYWORD_SEPARATOR));
    if (last_keyword_separator_pos == std::string::npos) // Not a chain, but an individual keyword!
        return geo_keyword_chain;
    return geo_keyword_chain.substr(last_keyword_separator_pos + 1);
}

std::string &NormaliseLocation(std::string * const location) {
    const auto comma_space_pos(location->find(", "));
    if (comma_space_pos != std::string::npos) {
        const auto auxillary_location(location->substr(comma_space_pos + 2));
        location->resize(comma_space_pos);
        *location += " <";
        *location += auxillary_location;
        *location += '>';
    }

    return *location;
}

std::string ExtractGeoKeyword(const MARC::Record::Field &_689_field) {
    if (_689_field.getFirstSubfieldWithCode('D') != "g")
        return "";

    std::string geo_keyword(_689_field.getFirstSubfieldWithCode('a'));
    const auto subfield_g_contents(_689_field.getFirstSubfieldWithCode('g'));
    if (subfield_g_contents.empty())
        return geo_keyword;
    return geo_keyword + " <" + subfield_g_contents + ">";
}

// Returns true if we added "new_689_contents" in a new 689 field, else false.
bool Add689GeographicKeywordIfMissing(MARC::Record * const record, const std::string &new_689_contents) {
    const MARC::Record::Field new_689_field(MARC::Tag("689"), new_689_contents);
    const std::string new_geo_keyword(ExtractGeoKeyword(new_689_field));
    for (const auto &_689_field : record->getTagRange("689")) {
        if (ExtractGeoKeyword(_689_field) == new_geo_keyword)
            return false; // New geographic keyword is not needed because we already have it!
    }

    record->insertField(new_689_field);
    return true;
}

void GenerateExpandedGeographicCodes(MARC::Reader * const reader, MARC::Writer * writer,
                                     const std::unordered_map<std::string, std::string> &codes_to_keyword_chains_map,
                                     const std::unordered_map<std::string, std::string> &locations_to_689_contents_map)
{
    unsigned total_count(0), conversion_count(0), _689_addition_count(0);
    while (auto record = reader->read()) {
        ++total_count;

        const auto _044_field(record.findTag("044"));
        if (_044_field == record.end()) {
            writer->write(record);
            continue;
        }

        const auto codes(_044_field->getFirstSubfieldWithCode('c'));
        if (codes.empty()) {
            writer->write(record);
            continue;
        }

        const auto codes_and_keyword_chain(codes_to_keyword_chains_map.find(codes));
        if (unlikely(codes_and_keyword_chain == codes_to_keyword_chains_map.cend()))
            LOG_WARNING("record w/ PPN " + record.getControlNumber() + " contains missing code \""
                        + codes + "\" in 044$c!");
        else {
            auto most_specific_location(GetMostSpecificGeographicLocation(codes_and_keyword_chain->second));
            NormaliseLocation(&most_specific_location);
            const auto most_specific_location_and_689_contents(locations_to_689_contents_map.find(most_specific_location));
            if (unlikely(most_specific_location_and_689_contents == locations_to_689_contents_map.cend()))
                LOG_WARNING("did not find \"" + most_specific_location + "\" in the locations to 689-contents map!");
            else if (Add689GeographicKeywordIfMissing(&record, most_specific_location_and_689_contents->second))
                ++_689_addition_count;

            record.insertField("GEO", 'a', codes_and_keyword_chain->second);
            ++conversion_count;
        }

        writer->write(record);
    }

    LOG_INFO("Processed " + std::to_string(total_count) + " record(s), converted "
             + std::to_string(conversion_count) + " code(s) to keyword chains and added "
             + std::to_string(_689_addition_count) + " new 689 normalised keyword(s).");
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 3)
        ::Usage("marc_input marc_output");

    std::unordered_map<std::string, std::string> codes_to_keyword_chains_map;
    InitialiseCodesToKeywordChainsMap(&codes_to_keyword_chains_map);

    std::unordered_map<std::string, std::string> locations_to_689_contents_map;
    InitialiseLocationTo689ContentsMap(&locations_to_689_contents_map);

    const auto marc_reader(MARC::Reader::Factory(argv[1]));
    const auto marc_writer(MARC::Writer::Factory(argv[2]));
    GenerateExpandedGeographicCodes(marc_reader.get(), marc_writer.get(), codes_to_keyword_chains_map,
                                    locations_to_689_contents_map);

    return EXIT_SUCCESS;
}
<|endoftext|>