<commit_before>/*
* Counter mode
* (C) 1999-2011,2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/ctr.h>
#include <botan/exceptn.h>
#include <botan/loadstor.h>

namespace Botan {

CTR_BE::CTR_BE(BlockCipher* ciph) :
   m_cipher(ciph),
   m_block_size(m_cipher->block_size()),
   m_ctr_size(m_block_size),
   m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size),
   m_counter(m_cipher->parallel_bytes()),
   m_pad(m_counter.size()),
   m_pad_pos(0)
   {
   }

CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) :
   m_cipher(cipher),
   m_block_size(m_cipher->block_size()),
   m_ctr_size(ctr_size),
   m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size),
   m_counter(m_cipher->parallel_bytes()),
   m_pad(m_counter.size()),
   m_pad_pos(0)
   {
   BOTAN_ARG_CHECK(m_ctr_size >= 4 && m_ctr_size <= m_block_size,
                   "Invalid CTR-BE counter size");
   }

void CTR_BE::clear()
   {
   m_cipher->clear();
   zeroise(m_pad);
   zeroise(m_counter);
   zap(m_iv);
   m_pad_pos = 0;
   }

size_t CTR_BE::default_iv_length() const
   {
   return m_block_size;
   }

bool CTR_BE::valid_iv_length(size_t iv_len) const
   {
   return (iv_len <= m_block_size);
   }

Key_Length_Specification CTR_BE::key_spec() const
   {
   return m_cipher->key_spec();
   }

CTR_BE* CTR_BE::clone() const
   {
   return new CTR_BE(m_cipher->clone(), m_ctr_size);
   }

void CTR_BE::key_schedule(const uint8_t key[], size_t key_len)
   {
   m_cipher->set_key(key, key_len);

   // Set a default all-zeros IV
   set_iv(nullptr, 0);
   }

std::string CTR_BE::name() const
   {
   if(m_ctr_size == m_block_size)
      return ("CTR-BE(" + m_cipher->name() + ")");
   else
      return ("CTR-BE(" + m_cipher->name() + "," + std::to_string(m_ctr_size) + ")");

   }

void CTR_BE::cipher(const uint8_t in[], uint8_t out[], size_t length)
   {
   verify_key_set(m_iv.empty() == false);

   const uint8_t* pad_bits = &m_pad[0];
   const size_t pad_size = m_pad.size();

   if(m_pad_pos > 0)
      {
      const size_t avail = pad_size - m_pad_pos;
      const size_t take = std::min(length, avail);
      xor_buf(out, in, pad_bits + m_pad_pos, take);
      length -= take;
      in += take;
      out += take;
      m_pad_pos += take;

      if(take == avail)
         {
         add_counter(m_ctr_blocks);
         m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
         m_pad_pos = 0;
         }
      }

   while(length >= pad_size)
      {
      xor_buf(out, in, pad_bits, pad_size);
      length -= pad_size;
      in += pad_size;
      out += pad_size;

      add_counter(m_ctr_blocks);
      m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
      }

   xor_buf(out, in, pad_bits, length);
   m_pad_pos += length;
   }

void CTR_BE::set_iv(const uint8_t iv[], size_t iv_len)
   {
   if(!valid_iv_length(iv_len))
      throw Invalid_IV_Length(name(), iv_len);

   m_iv.resize(m_block_size);
   zeroise(m_iv);
   buffer_insert(m_iv, 0, iv, iv_len);

   seek(0);
   }

void CTR_BE::add_counter(const uint64_t counter)
   {
   const size_t ctr_size = m_ctr_size;
   const size_t ctr_blocks = m_ctr_blocks;
   const size_t BS = m_block_size;

   if(ctr_size == 4)
      {
      size_t off = (BS - 4);
      uint32_t low32 = static_cast<uint32_t>(counter + load_be<uint32_t>(&m_counter[off], 0));

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(low32, &m_counter[off]);
         off += BS;
         low32 += 1;
         }
      }
   else if(ctr_size == 8)
      {
      size_t off = (BS - 8);
      uint64_t low64 = counter + load_be<uint64_t>(&m_counter[off], 0);

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(low64, &m_counter[off]);
         off += BS;
         low64 += 1;
         }
      }
   else if(ctr_size == 16)
      {
      size_t off = (BS - 16);
      uint64_t b0 = load_be<uint64_t>(&m_counter[off], 0);
      uint64_t b1 = load_be<uint64_t>(&m_counter[off], 1);
      b1 += counter;
      b0 += (b1 < counter) ? 1 : 0; // carry

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(b0, &m_counter[off]);
         store_be(b1, &m_counter[off+8]);
         off += BS;
         b1 += 1;
         b0 += (b1 == 0); // carry
         }
      }
   else
      {
      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         uint64_t local_counter = counter;
         uint16_t carry = static_cast<uint8_t>(local_counter);
         for(size_t j = 0; (carry || local_counter) && j != ctr_size; ++j)
            {
            const size_t off = i*BS + (BS-1-j);
            const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry;
            m_counter[off] = static_cast<uint8_t>(cnt);
            local_counter = (local_counter >> 8);
            carry = (cnt >> 8) + static_cast<uint8_t>(local_counter);
            }
         }
      }
   }

void CTR_BE::seek(uint64_t offset)
   {
   verify_key_set(m_iv.empty() == false);

   const uint64_t base_counter = m_ctr_blocks * (offset / m_counter.size());

   zeroise(m_counter);
   buffer_insert(m_counter, 0, m_iv);

   const size_t BS = m_block_size;

   // Set m_counter blocks to IV, IV + 1, ... IV + n

   if(m_ctr_size == 4 && BS >= 8)
      {
      const uint32_t low32 = load_be<uint32_t>(&m_counter[BS-4], 0);
      for(size_t i = 1; i != m_ctr_blocks; ++i)
         {
         copy_mem(&m_counter[i*BS], &m_counter[0], BS);
         const uint32_t c = static_cast<uint32_t>(low32 + i);
         store_be(c, &m_counter[(BS-4)+i*BS]);
         }
      }
   else
      {
      for(size_t i = 1; i != m_ctr_blocks; ++i)
         {
         buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS);

         for(size_t j = 0; j != m_ctr_size; ++j)
            if(++m_counter[i*BS + (BS - 1 - j)])
               break;
         }
      }

   if(base_counter > 0)
      add_counter(base_counter);

   m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
   m_pad_pos = offset % m_counter.size();
   }
}
<commit_msg>Avoid pointless write<commit_after>/*
* Counter mode
* (C) 1999-2011,2014 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/ctr.h>
#include <botan/exceptn.h>
#include <botan/loadstor.h>

namespace Botan {

CTR_BE::CTR_BE(BlockCipher* ciph) :
   m_cipher(ciph),
   m_block_size(m_cipher->block_size()),
   m_ctr_size(m_block_size),
   m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size),
   m_counter(m_cipher->parallel_bytes()),
   m_pad(m_counter.size()),
   m_pad_pos(0)
   {
   }

CTR_BE::CTR_BE(BlockCipher* cipher, size_t ctr_size) :
   m_cipher(cipher),
   m_block_size(m_cipher->block_size()),
   m_ctr_size(ctr_size),
   m_ctr_blocks(m_cipher->parallel_bytes() / m_block_size),
   m_counter(m_cipher->parallel_bytes()),
   m_pad(m_counter.size()),
   m_pad_pos(0)
   {
   BOTAN_ARG_CHECK(m_ctr_size >= 4 && m_ctr_size <= m_block_size,
                   "Invalid CTR-BE counter size");
   }

void CTR_BE::clear()
   {
   m_cipher->clear();
   zeroise(m_pad);
   zeroise(m_counter);
   zap(m_iv);
   m_pad_pos = 0;
   }

size_t CTR_BE::default_iv_length() const
   {
   return m_block_size;
   }

bool CTR_BE::valid_iv_length(size_t iv_len) const
   {
   return (iv_len <= m_block_size);
   }

Key_Length_Specification CTR_BE::key_spec() const
   {
   return m_cipher->key_spec();
   }

CTR_BE* CTR_BE::clone() const
   {
   return new CTR_BE(m_cipher->clone(), m_ctr_size);
   }

void CTR_BE::key_schedule(const uint8_t key[], size_t key_len)
   {
   m_cipher->set_key(key, key_len);

   // Set a default all-zeros IV
   set_iv(nullptr, 0);
   }

std::string CTR_BE::name() const
   {
   if(m_ctr_size == m_block_size)
      return ("CTR-BE(" + m_cipher->name() + ")");
   else
      return ("CTR-BE(" + m_cipher->name() + "," + std::to_string(m_ctr_size) + ")");

   }

void CTR_BE::cipher(const uint8_t in[], uint8_t out[], size_t length)
   {
   verify_key_set(m_iv.empty() == false);

   const uint8_t* pad_bits = &m_pad[0];
   const size_t pad_size = m_pad.size();

   if(m_pad_pos > 0)
      {
      const size_t avail = pad_size - m_pad_pos;
      const size_t take = std::min(length, avail);
      xor_buf(out, in, pad_bits + m_pad_pos, take);
      length -= take;
      in += take;
      out += take;
      m_pad_pos += take;

      if(take == avail)
         {
         add_counter(m_ctr_blocks);
         m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
         m_pad_pos = 0;
         }
      }

   while(length >= pad_size)
      {
      xor_buf(out, in, pad_bits, pad_size);
      length -= pad_size;
      in += pad_size;
      out += pad_size;

      add_counter(m_ctr_blocks);
      m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
      }

   xor_buf(out, in, pad_bits, length);
   m_pad_pos += length;
   }

void CTR_BE::set_iv(const uint8_t iv[], size_t iv_len)
   {
   if(!valid_iv_length(iv_len))
      throw Invalid_IV_Length(name(), iv_len);

   m_iv.resize(m_block_size);
   zeroise(m_iv);
   buffer_insert(m_iv, 0, iv, iv_len);

   seek(0);
   }

void CTR_BE::add_counter(const uint64_t counter)
   {
   const size_t ctr_size = m_ctr_size;
   const size_t ctr_blocks = m_ctr_blocks;
   const size_t BS = m_block_size;

   if(ctr_size == 4)
      {
      size_t off = (BS - 4);
      uint32_t low32 = static_cast<uint32_t>(counter + load_be<uint32_t>(&m_counter[off], 0));

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(low32, &m_counter[off]);
         off += BS;
         low32 += 1;
         }
      }
   else if(ctr_size == 8)
      {
      size_t off = (BS - 8);
      uint64_t low64 = counter + load_be<uint64_t>(&m_counter[off], 0);

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(low64, &m_counter[off]);
         off += BS;
         low64 += 1;
         }
      }
   else if(ctr_size == 16)
      {
      size_t off = (BS - 16);
      uint64_t b0 = load_be<uint64_t>(&m_counter[off], 0);
      uint64_t b1 = load_be<uint64_t>(&m_counter[off], 1);
      b1 += counter;
      b0 += (b1 < counter) ? 1 : 0; // carry

      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         store_be(b0, &m_counter[off]);
         store_be(b1, &m_counter[off+8]);
         off += BS;
         b1 += 1;
         b0 += (b1 == 0); // carry
         }
      }
   else
      {
      for(size_t i = 0; i != ctr_blocks; ++i)
         {
         uint64_t local_counter = counter;
         uint16_t carry = static_cast<uint8_t>(local_counter);
         for(size_t j = 0; (carry || local_counter) && j != ctr_size; ++j)
            {
            const size_t off = i*BS + (BS-1-j);
            const uint16_t cnt = static_cast<uint16_t>(m_counter[off]) + carry;
            m_counter[off] = static_cast<uint8_t>(cnt);
            local_counter = (local_counter >> 8);
            carry = (cnt >> 8) + static_cast<uint8_t>(local_counter);
            }
         }
      }
   }

void CTR_BE::seek(uint64_t offset)
   {
   verify_key_set(m_iv.empty() == false);

   const uint64_t base_counter = m_ctr_blocks * (offset / m_counter.size());

   zeroise(m_counter);
   buffer_insert(m_counter, 0, m_iv);

   const size_t BS = m_block_size;

   // Set m_counter blocks to IV, IV + 1, ... IV + n

   if(m_ctr_size == 4 && BS >= 8)
      {
      const uint32_t low32 = load_be<uint32_t>(&m_counter[BS-4], 0);
      for(size_t i = 1; i != m_ctr_blocks; ++i)
         {
         copy_mem(&m_counter[i*BS], &m_counter[0], BS - 4);
         const uint32_t c = static_cast<uint32_t>(low32 + i);
         store_be(c, &m_counter[(BS-4)+i*BS]);
         }
      }
   else
      {
      for(size_t i = 1; i != m_ctr_blocks; ++i)
         {
         buffer_insert(m_counter, i*BS, &m_counter[(i-1)*BS], BS);

         for(size_t j = 0; j != m_ctr_size; ++j)
            if(++m_counter[i*BS + (BS - 1 - j)])
               break;
         }
      }

   if(base_counter > 0)
      add_counter(base_counter);

   m_cipher->encrypt_n(m_counter.data(), m_pad.data(), m_ctr_blocks);
   m_pad_pos = offset % m_counter.size();
   }
}
<|endoftext|>


<commit_before><commit_msg>Fix use of or<commit_after><|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "masterrenderer.h"

// appleseed.renderer headers.
#include "renderer/global/globallogger.h"
#include "renderer/kernel/rendering/iframerenderer.h"
#ifdef APPLESEED_WITH_OIIO
#include "renderer/kernel/rendering/oiiocomponents.h"
#endif
#ifdef APPLESEED_WITH_OSL
#include "renderer/kernel/rendering/oslcomponents.h"
#include "renderer/kernel/rendering/rendererservices.h"
#endif
#include "renderer/kernel/rendering/renderercomponents.h"
#include "renderer/kernel/rendering/serialrenderercontroller.h"
#include "renderer/kernel/rendering/serialtilecallback.h"
#include "renderer/kernel/texturing/texturestore.h"
#include "renderer/modeling/display/display.h"
#include "renderer/modeling/frame/frame.h"
#include "renderer/modeling/input/inputbinder.h"
#include "renderer/modeling/project/project.h"
#include "renderer/modeling/scene/scene.h"

// appleseed.foundation headers.
#include "foundation/platform/compiler.h"
#include "foundation/platform/thread.h"
#include "foundation/utility/job/iabortswitch.h"
#include "foundation/utility/otherwise.h"
#include "foundation/utility/statistics.h"

// Standard headers.
#include <cassert>
#include <exception>
#include <string>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// MasterRenderer class implementation.
//

MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    IRendererController*    renderer_controller,
    ITileCallbackFactory*   tile_callback_factory)
  : m_project(project)
  , m_params(params)
  , m_renderer_controller(renderer_controller)
  , m_tile_callback_factory(tile_callback_factory)
  , m_serial_renderer_controller(0)
  , m_serial_tile_callback_factory(0)
{
}

MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    IRendererController*    renderer_controller,
    ITileCallback*          tile_callback)
  : m_project(project)
  , m_params(params)
  , m_serial_renderer_controller(new SerialRendererController(renderer_controller, tile_callback))
  , m_serial_tile_callback_factory(new SerialTileCallbackFactory(m_serial_renderer_controller))
{
    m_renderer_controller = m_serial_renderer_controller;
    m_tile_callback_factory = m_serial_tile_callback_factory;
}

MasterRenderer::~MasterRenderer()
{
    delete m_serial_tile_callback_factory;
    delete m_serial_renderer_controller;
}

ParamArray& MasterRenderer::get_parameters()
{
    return m_params;
}

const ParamArray& MasterRenderer::get_parameters() const
{
    return m_params;
}

bool MasterRenderer::render()
{
    try
    {
        do_render();
        return true;
    }
    catch (const bad_alloc&)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (ran out of memory).");
        return false;
    }
#ifdef NDEBUG
    catch (const exception& e)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (%s).", e.what());
        return false;
    }
    catch (...)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (unknown exception).");
        return false;
    }
#endif
}

void MasterRenderer::do_render()
{
    while (true)
    {
        m_renderer_controller->on_rendering_begin();

        const IRendererController::Status status = initialize_and_render_frame_sequence();

        switch (status)
        {
          case IRendererController::TerminateRendering:
            m_renderer_controller->on_rendering_success();
            return;

          case IRendererController::AbortRendering:
            m_renderer_controller->on_rendering_abort();
            return;

          case IRendererController::ReinitializeRendering:
            break;

          assert_otherwise;
        }
    }
}

namespace
{
    // RAII-style handling of display plugins.
    class CloseDisplayPluginOnScopeExit
      : public NonCopyable
    {
      public:
        CloseDisplayPluginOnScopeExit()
          : m_display(0)
        {
        }

        ~CloseDisplayPluginOnScopeExit()
        {
            if (m_display)
                m_display->close();
        }

        void set_display(Display* display)
        {
            m_display = display;
        }

      private:
        Display* m_display;
    };

    // An abort switch whose abort status is determined by a renderer::IRendererController.
    class RendererControllerAbortSwitch
      : public IAbortSwitch
    {
      public:
        explicit RendererControllerAbortSwitch(IRendererController& renderer_controller)
          : m_renderer_controller(renderer_controller)
        {
        }

        virtual bool is_aborted() const APPLESEED_OVERRIDE
        {
            const IRendererController::Status status = m_renderer_controller.get_status();
            return
                status != IRendererController::ContinueRendering &&
                status != IRendererController::RestartRendering;
        }

      private:
        IRendererController& m_renderer_controller;
    };
}

IRendererController::Status MasterRenderer::initialize_and_render_frame_sequence()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Construct an abort switch based on the renderer controller.
    RendererControllerAbortSwitch abort_switch(*m_renderer_controller);

    // We start by binding entities inputs. This must be done before creating/updating the trace context.
    if (!bind_scene_entities_inputs())
        return IRendererController::AbortRendering;

    m_project.create_aov_images();
    m_project.update_trace_context();
    m_project.get_frame()->print_settings();

    // Create the texture store.
    TextureStore texture_store(
        *m_project.get_scene(),
        m_params.child("texture_store"));

#ifdef APPLESEED_WITH_OIIO

    // Initialize OIIO.
    OIIOComponents oiio_components(m_project, m_params);

#endif

#ifdef APPLESEED_WITH_OSL

    // Initialize OSL.
    OSLComponents osl_components(
        m_project,
        texture_store,
        oiio_components.get_texture_system());

    // Compile OSL shaders.
    if (!osl_components.compile_osl_shaders(&abort_switch))
        return IRendererController::AbortRendering;

    // Don't proceed further if rendering was aborted.
    if (abort_switch.is_aborted())
        return m_renderer_controller->get_status();

#endif

    // If needed, open the display plugin.
    CloseDisplayPluginOnScopeExit close_display;
    ITileCallbackFactory* tile_callback_factory = m_tile_callback_factory;
    if (tile_callback_factory == 0)
    {
        if (Display* display = m_project.get_display())
        {
            display->open(m_project);
            close_display.set_display(display);
            tile_callback_factory = display->get_tile_callback_factory();
        }
    }

    // Create the renderer components.
    RendererComponents components(
        m_project,
        m_params,
        m_tile_callback_factory,
        texture_store
#ifdef APPLESEED_WITH_OIIO
        , oiio_components.get_texture_system()
#endif
#ifdef APPLESEED_WITH_OSL
        , osl_components.get_shading_system()
#endif
        );
    if (!components.initialize())
        return IRendererController::AbortRendering;

    // Execute the main rendering loop.
    const IRendererController::Status status =
        render_frame_sequence(
            components.get_frame_renderer()
#ifdef APPLESEED_WITH_OSL
            , osl_components.get_renderer_services()
#endif
            , abort_switch);

    // Print texture store performance statistics.
    RENDERER_LOG_DEBUG("%s", texture_store.get_statistics().to_string().c_str());

    return status;
}

IRendererController::Status MasterRenderer::render_frame_sequence(
    IFrameRenderer&         frame_renderer
#ifdef APPLESEED_WITH_OSL
    , RendererServices&     renderer_services
#endif
    , IAbortSwitch&         abort_switch)
{
    while (true)
    {
        assert(!frame_renderer.is_rendering());

        // The on_frame_begin() method of the renderer controller might alter the scene
        // (e.g. transform the camera), thus it needs to be called before the on_frame_begin()
        // of the scene which assumes the scene is up-to-date and ready to be rendered.
        m_renderer_controller->on_frame_begin();

        // Prepare the scene for rendering. Don't proceed if that failed.
        if (!m_project.get_scene()->on_frame_begin(m_project, &abort_switch))
        {
            m_renderer_controller->on_frame_end();
            return IRendererController::AbortRendering;
        }

        // Don't proceed with rendering if scene preparation was aborted.
        if (abort_switch.is_aborted())
        {
            m_renderer_controller->on_frame_end();
            return m_renderer_controller->get_status();
        }

#ifdef APPLESEED_WITH_OSL
        renderer_services.initialize();
#endif

        frame_renderer.start_rendering();

        const IRendererController::Status status = wait_for_event(frame_renderer);

        switch (status)
        {
          case IRendererController::TerminateRendering:
          case IRendererController::AbortRendering:
          case IRendererController::ReinitializeRendering:
            frame_renderer.terminate_rendering();
            break;

          case IRendererController::RestartRendering:
            frame_renderer.stop_rendering();
            break;

          assert_otherwise;
        }

        assert(!frame_renderer.is_rendering());

        m_project.get_scene()->on_frame_end(m_project);
        m_renderer_controller->on_frame_end();

        switch (status)
        {
          case IRendererController::TerminateRendering:
          case IRendererController::AbortRendering:
          case IRendererController::ReinitializeRendering:
            return status;

          case IRendererController::RestartRendering:
            break;

          assert_otherwise;
        }
    }
}

IRendererController::Status MasterRenderer::wait_for_event(IFrameRenderer& frame_renderer) const
{
    while (true)
    {
        if (!frame_renderer.is_rendering())
            return IRendererController::TerminateRendering;

        const IRendererController::Status status = m_renderer_controller->get_status();

        if (status != IRendererController::ContinueRendering)
            return status;

        m_renderer_controller->on_progress();

        foundation::sleep(1);   // namespace qualifer required
    }
}

bool MasterRenderer::bind_scene_entities_inputs() const
{
    InputBinder input_binder;
    input_binder.bind(*m_project.get_scene());
    return input_binder.get_error_count() == 0;
}

}   // namespace renderer
<commit_msg>Fix display driver initialization bug<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "masterrenderer.h"

// appleseed.renderer headers.
#include "renderer/global/globallogger.h"
#include "renderer/kernel/rendering/iframerenderer.h"
#ifdef APPLESEED_WITH_OIIO
#include "renderer/kernel/rendering/oiiocomponents.h"
#endif
#ifdef APPLESEED_WITH_OSL
#include "renderer/kernel/rendering/oslcomponents.h"
#include "renderer/kernel/rendering/rendererservices.h"
#endif
#include "renderer/kernel/rendering/renderercomponents.h"
#include "renderer/kernel/rendering/serialrenderercontroller.h"
#include "renderer/kernel/rendering/serialtilecallback.h"
#include "renderer/kernel/texturing/texturestore.h"
#include "renderer/modeling/display/display.h"
#include "renderer/modeling/frame/frame.h"
#include "renderer/modeling/input/inputbinder.h"
#include "renderer/modeling/project/project.h"
#include "renderer/modeling/scene/scene.h"

// appleseed.foundation headers.
#include "foundation/platform/compiler.h"
#include "foundation/platform/thread.h"
#include "foundation/utility/job/iabortswitch.h"
#include "foundation/utility/otherwise.h"
#include "foundation/utility/statistics.h"

// Standard headers.
#include <cassert>
#include <exception>
#include <string>

using namespace foundation;
using namespace std;

namespace renderer
{

//
// MasterRenderer class implementation.
//

MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    IRendererController*    renderer_controller,
    ITileCallbackFactory*   tile_callback_factory)
  : m_project(project)
  , m_params(params)
  , m_renderer_controller(renderer_controller)
  , m_tile_callback_factory(tile_callback_factory)
  , m_serial_renderer_controller(0)
  , m_serial_tile_callback_factory(0)
{
}

MasterRenderer::MasterRenderer(
    Project&                project,
    const ParamArray&       params,
    IRendererController*    renderer_controller,
    ITileCallback*          tile_callback)
  : m_project(project)
  , m_params(params)
  , m_serial_renderer_controller(new SerialRendererController(renderer_controller, tile_callback))
  , m_serial_tile_callback_factory(new SerialTileCallbackFactory(m_serial_renderer_controller))
{
    m_renderer_controller = m_serial_renderer_controller;
    m_tile_callback_factory = m_serial_tile_callback_factory;
}

MasterRenderer::~MasterRenderer()
{
    delete m_serial_tile_callback_factory;
    delete m_serial_renderer_controller;
}

ParamArray& MasterRenderer::get_parameters()
{
    return m_params;
}

const ParamArray& MasterRenderer::get_parameters() const
{
    return m_params;
}

bool MasterRenderer::render()
{
    try
    {
        do_render();
        return true;
    }
    catch (const bad_alloc&)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (ran out of memory).");
        return false;
    }
#ifdef NDEBUG
    catch (const exception& e)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (%s).", e.what());
        return false;
    }
    catch (...)
    {
        m_renderer_controller->on_rendering_abort();
        RENDERER_LOG_ERROR("rendering failed (unknown exception).");
        return false;
    }
#endif
}

void MasterRenderer::do_render()
{
    while (true)
    {
        m_renderer_controller->on_rendering_begin();

        const IRendererController::Status status = initialize_and_render_frame_sequence();

        switch (status)
        {
          case IRendererController::TerminateRendering:
            m_renderer_controller->on_rendering_success();
            return;

          case IRendererController::AbortRendering:
            m_renderer_controller->on_rendering_abort();
            return;

          case IRendererController::ReinitializeRendering:
            break;

          assert_otherwise;
        }
    }
}

namespace
{
    // RAII-style handling of display plugins.
    class CloseDisplayPluginOnScopeExit
      : public NonCopyable
    {
      public:
        CloseDisplayPluginOnScopeExit()
          : m_display(0)
        {
        }

        ~CloseDisplayPluginOnScopeExit()
        {
            if (m_display)
                m_display->close();
        }

        void set_display(Display* display)
        {
            m_display = display;
        }

      private:
        Display* m_display;
    };

    // An abort switch whose abort status is determined by a renderer::IRendererController.
    class RendererControllerAbortSwitch
      : public IAbortSwitch
    {
      public:
        explicit RendererControllerAbortSwitch(IRendererController& renderer_controller)
          : m_renderer_controller(renderer_controller)
        {
        }

        virtual bool is_aborted() const APPLESEED_OVERRIDE
        {
            const IRendererController::Status status = m_renderer_controller.get_status();
            return
                status != IRendererController::ContinueRendering &&
                status != IRendererController::RestartRendering;
        }

      private:
        IRendererController& m_renderer_controller;
    };
}

IRendererController::Status MasterRenderer::initialize_and_render_frame_sequence()
{
    assert(m_project.get_scene());
    assert(m_project.get_frame());

    // Construct an abort switch based on the renderer controller.
    RendererControllerAbortSwitch abort_switch(*m_renderer_controller);

    // We start by binding entities inputs. This must be done before creating/updating the trace context.
    if (!bind_scene_entities_inputs())
        return IRendererController::AbortRendering;

    m_project.create_aov_images();
    m_project.update_trace_context();
    m_project.get_frame()->print_settings();

    // Create the texture store.
    TextureStore texture_store(
        *m_project.get_scene(),
        m_params.child("texture_store"));

#ifdef APPLESEED_WITH_OIIO

    // Initialize OIIO.
    OIIOComponents oiio_components(m_project, m_params);

#endif

#ifdef APPLESEED_WITH_OSL

    // Initialize OSL.
    OSLComponents osl_components(
        m_project,
        texture_store,
        oiio_components.get_texture_system());

    // Compile OSL shaders.
    if (!osl_components.compile_osl_shaders(&abort_switch))
        return IRendererController::AbortRendering;

    // Don't proceed further if rendering was aborted.
    if (abort_switch.is_aborted())
        return m_renderer_controller->get_status();

#endif

    // If needed, open the display plugin.
    CloseDisplayPluginOnScopeExit close_display;
    ITileCallbackFactory* tile_callback_factory = m_tile_callback_factory;
    if (tile_callback_factory == 0)
    {
        if (Display* display = m_project.get_display())
        {
            display->open(m_project);
            close_display.set_display(display);
            tile_callback_factory = display->get_tile_callback_factory();
        }
    }

    // Create the renderer components.
    RendererComponents components(
        m_project,
        m_params,
        tile_callback_factory,
        texture_store
#ifdef APPLESEED_WITH_OIIO
        , oiio_components.get_texture_system()
#endif
#ifdef APPLESEED_WITH_OSL
        , osl_components.get_shading_system()
#endif
        );
    if (!components.initialize())
        return IRendererController::AbortRendering;

    // Execute the main rendering loop.
    const IRendererController::Status status =
        render_frame_sequence(
            components.get_frame_renderer()
#ifdef APPLESEED_WITH_OSL
            , osl_components.get_renderer_services()
#endif
            , abort_switch);

    // Print texture store performance statistics.
    RENDERER_LOG_DEBUG("%s", texture_store.get_statistics().to_string().c_str());

    return status;
}

IRendererController::Status MasterRenderer::render_frame_sequence(
    IFrameRenderer&         frame_renderer
#ifdef APPLESEED_WITH_OSL
    , RendererServices&     renderer_services
#endif
    , IAbortSwitch&         abort_switch)
{
    while (true)
    {
        assert(!frame_renderer.is_rendering());

        // The on_frame_begin() method of the renderer controller might alter the scene
        // (e.g. transform the camera), thus it needs to be called before the on_frame_begin()
        // of the scene which assumes the scene is up-to-date and ready to be rendered.
        m_renderer_controller->on_frame_begin();

        // Prepare the scene for rendering. Don't proceed if that failed.
        if (!m_project.get_scene()->on_frame_begin(m_project, &abort_switch))
        {
            m_renderer_controller->on_frame_end();
            return IRendererController::AbortRendering;
        }

        // Don't proceed with rendering if scene preparation was aborted.
        if (abort_switch.is_aborted())
        {
            m_renderer_controller->on_frame_end();
            return m_renderer_controller->get_status();
        }

#ifdef APPLESEED_WITH_OSL
        renderer_services.initialize();
#endif

        frame_renderer.start_rendering();

        const IRendererController::Status status = wait_for_event(frame_renderer);

        switch (status)
        {
          case IRendererController::TerminateRendering:
          case IRendererController::AbortRendering:
          case IRendererController::ReinitializeRendering:
            frame_renderer.terminate_rendering();
            break;

          case IRendererController::RestartRendering:
            frame_renderer.stop_rendering();
            break;

          assert_otherwise;
        }

        assert(!frame_renderer.is_rendering());

        m_project.get_scene()->on_frame_end(m_project);
        m_renderer_controller->on_frame_end();

        switch (status)
        {
          case IRendererController::TerminateRendering:
          case IRendererController::AbortRendering:
          case IRendererController::ReinitializeRendering:
            return status;

          case IRendererController::RestartRendering:
            break;

          assert_otherwise;
        }
    }
}

IRendererController::Status MasterRenderer::wait_for_event(IFrameRenderer& frame_renderer) const
{
    while (true)
    {
        if (!frame_renderer.is_rendering())
            return IRendererController::TerminateRendering;

        const IRendererController::Status status = m_renderer_controller->get_status();

        if (status != IRendererController::ContinueRendering)
            return status;

        m_renderer_controller->on_progress();

        foundation::sleep(1);   // namespace qualifer required
    }
}

bool MasterRenderer::bind_scene_entities_inputs() const
{
    InputBinder input_binder;
    input_binder.bind(*m_project.get_scene());
    return input_binder.get_error_count() == 0;
}

}   // namespace renderer
<|endoftext|>


<commit_before>/*
The MIT License

Copyright (c) 2017-2017 Albert Murienne

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "tiny_dnn/tiny_dnn.h"

#include "adamax.h"

#include <iostream>

using namespace tiny_dnn;
using namespace tiny_dnn::layers;
using namespace tiny_dnn::activation;

static void construct_net(  network<sequential> &nn, core::backend_t backend_type )
{
    // construct nets
    //
    // C : convolution
    // S : sub-sampling
    // F : fully connected
    // clang-format off
    nn  << conv( 32, 32, 5, 1, 12 ) << relu() // C1, 1@32x32-in, 12@28x28-out
        << max_pool( 28, 28, 12, 2 ) // S2, 12@28x28-in, 12@14x14-out
        << conv( 14, 14, 5, 12, 25 ) << relu() // C3, 12@14x14-in, 25@10x10-out
        << max_pool( 10, 10, 25, 2 ) // S4, 25@10x10-in, 25@5x5-out
        << fc( 625, 180 ) << relu() // F5, 625-in, 180-out
        << dropout( 180, 0.5f )
        << fc( 180, 100 ) << relu() // F6, 180-in, 100-out
        << dropout( 100, 0.5f )
        << fc( 100, 10 ) << softmax_layer(10); // F7, 100-in, 10-out
    // clang-format on

    nn.weight_init( weight_init::he() );
    nn.bias_init( weight_init::he() );
}

static void train_mnist(    const std::string &data_dir_path,
                            const int n_train_epochs,
                            const int n_minibatch,
                            core::backend_t backend_type )
{
    // specify loss-function and learning strategy
    network<sequential> nn;
    adamax optimizer;

    construct_net( nn, backend_type );

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels( data_dir_path + "/train-labels.idx1-ubyte", &train_labels);
    parse_mnist_images( data_dir_path + "/train-images.idx3-ubyte", &train_images, -1.0, 1.0, 2, 2 );
    parse_mnist_labels( data_dir_path + "/t10k-labels.idx1-ubyte", &test_labels);
    parse_mnist_images( data_dir_path + "/t10k-images.idx3-ubyte", &test_images, -1.0, 1.0, 2, 2 );

    std::cout << "start training" << std::endl;

    progress_display disp( train_images.size() );
    timer t;

    // What is this for?
    //optimizer.alpha *= std::min( tiny_dnn::float_t(4),
    //    static_cast<tiny_dnn::float_t>( sqrt( n_minibatch ) * learning_rate ) );

    int epoch = 1;

    // create callback
    auto on_enumerate_epoch = [&]() {
        std::cout << "Epoch " << epoch << "/" << n_train_epochs << " finished. "
            << t.elapsed() << "s elapsed." << std::endl;
        ++epoch;
        tiny_dnn::result res = nn.test( test_images, test_labels );
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart( train_images.size() );
        t.restart();
    };

    auto on_enumerate_minibatch = [&]() { disp += n_minibatch; };

    // training
    nn.train<cross_entropy_multiclass>( optimizer, train_images, train_labels, n_minibatch,
        n_train_epochs, on_enumerate_minibatch, on_enumerate_epoch );

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test( test_images, test_labels ).print_detail( std::cout );
    // save network model & trained weights
    nn.save( "kaggle-mnist-model" );
}

static void usage( const char *argv0 )
{
    std::cout   << "Usage: " << argv0 << " --data_path path_to_dataset_folder" << std::endl;
}

int main( int argc, char **argv )
{
    std::string data_path        = "";
    int epochs                   = 30;
    int minibatch_size           = 128;
    core::backend_t backend_type = core::default_engine();

    if ( argc == 2 )
    {
        std::string argname( argv[1] );
        if ( argname == "--help" || argname == "-h" )
        {
            usage( argv[0] );
            return 0;
        }
    }
    else if ( argc == 4 )
    {
        std::string argname(argv[3]);
        if ( argname == "--data_path" )
        {
            data_path = std::string( argv[4] );
        }
    }
    else
    {
        std::cerr << "Invalid command line" << std::endl;
        usage( argv[0] );
        return -1;
    }

    if ( data_path == "" )
    {
        std::cerr << "Data path not specified." << std::endl;
        usage( argv[0] );
        return -1;
    }
    std::cout   << "Running with the following parameters:" << std::endl
                << "Data path: " << data_path << std::endl
                << std::endl;
    try
    {
        train_mnist( data_path, epochs, minibatch_size, backend_type );
    }
    catch( tiny_dnn::nn_error &err )
    {
        std::cerr << "Exception: " << err.what() << std::endl;
    }
    return 0;
}
<commit_msg>- messed up up with the args management.<commit_after>/*
The MIT License

Copyright (c) 2017-2017 Albert Murienne

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "tiny_dnn/tiny_dnn.h"

#include "adamax.h"

#include <iostream>

using namespace tiny_dnn;
using namespace tiny_dnn::layers;
using namespace tiny_dnn::activation;

static void construct_net(  network<sequential> &nn, core::backend_t backend_type )
{
    // construct nets
    //
    // C : convolution
    // S : sub-sampling
    // F : fully connected
    // clang-format off
    nn  << conv( 32, 32, 5, 1, 12 ) << relu() // C1, 1@32x32-in, 12@28x28-out
        << max_pool( 28, 28, 12, 2 ) // S2, 12@28x28-in, 12@14x14-out
        << conv( 14, 14, 5, 12, 25 ) << relu() // C3, 12@14x14-in, 25@10x10-out
        << max_pool( 10, 10, 25, 2 ) // S4, 25@10x10-in, 25@5x5-out
        << fc( 625, 180 ) << relu() // F5, 625-in, 180-out
        << dropout( 180, 0.5f )
        << fc( 180, 100 ) << relu() // F6, 180-in, 100-out
        << dropout( 100, 0.5f )
        << fc( 100, 10 ) << softmax_layer(10); // F7, 100-in, 10-out
    // clang-format on

    nn.weight_init( weight_init::he() );
    nn.bias_init( weight_init::he() );
}

static void train_mnist(    const std::string &data_dir_path,
                            const int n_train_epochs,
                            const int n_minibatch,
                            core::backend_t backend_type )
{
    // specify loss-function and learning strategy
    network<sequential> nn;
    adamax optimizer;

    construct_net( nn, backend_type );

    std::cout << "load models..." << std::endl;

    // load MNIST dataset
    std::vector<label_t> train_labels, test_labels;
    std::vector<vec_t> train_images, test_images;

    parse_mnist_labels( data_dir_path + "/train-labels.idx1-ubyte", &train_labels);
    parse_mnist_images( data_dir_path + "/train-images.idx3-ubyte", &train_images, -1.0, 1.0, 2, 2 );
    parse_mnist_labels( data_dir_path + "/t10k-labels.idx1-ubyte", &test_labels);
    parse_mnist_images( data_dir_path + "/t10k-images.idx3-ubyte", &test_images, -1.0, 1.0, 2, 2 );

    std::cout << "start training" << std::endl;

    progress_display disp( train_images.size() );
    timer t;

    // What is this for?
    //optimizer.alpha *= std::min( tiny_dnn::float_t(4),
    //    static_cast<tiny_dnn::float_t>( sqrt( n_minibatch ) * learning_rate ) );

    int epoch = 1;

    // create callback
    auto on_enumerate_epoch = [&]() {
        std::cout << "Epoch " << epoch << "/" << n_train_epochs << " finished. "
            << t.elapsed() << "s elapsed." << std::endl;
        ++epoch;
        tiny_dnn::result res = nn.test( test_images, test_labels );
        std::cout << res.num_success << "/" << res.num_total << std::endl;

        disp.restart( train_images.size() );
        t.restart();
    };

    auto on_enumerate_minibatch = [&]() { disp += n_minibatch; };

    // training
    nn.train<cross_entropy_multiclass>( optimizer, train_images, train_labels, n_minibatch,
        n_train_epochs, on_enumerate_minibatch, on_enumerate_epoch );

    std::cout << "end training." << std::endl;

    // test and show results
    nn.test( test_images, test_labels ).print_detail( std::cout );
    // save network model & trained weights
    nn.save( "kaggle-mnist-model" );
}

static void usage( const char *argv0 )
{
    std::cout   << "Usage: " << argv0 << " --data_path path_to_dataset_folder" << std::endl;
}

int main( int argc, char **argv )
{
    std::string data_path        = "";
    int epochs                   = 30;
    int minibatch_size           = 128;
    core::backend_t backend_type = core::default_engine();

    if ( argc == 2 )
    {
        std::string argname( argv[1] );
        if ( argname == "--help" || argname == "-h" )
        {
            usage( argv[0] );
            return 0;
        }
    }
    else if ( argc == 3 )
    {
        std::string argname(argv[1]);
        if ( argname == "--data_path" )
        {
            data_path = std::string( argv[2] );
        }
    }
    else
    {
        std::cerr << "Invalid command line" << std::endl;
        usage( argv[0] );
        return -1;
    }

    if ( data_path == "" )
    {
        std::cerr << "Data path not specified." << std::endl;
        usage( argv[0] );
        return -1;
    }
    std::cout   << "Running with the following parameters:" << std::endl
                << "Data path: " << data_path << std::endl
                << std::endl;
    try
    {
        train_mnist( data_path, epochs, minibatch_size, backend_type );
    }
    catch( tiny_dnn::nn_error &err )
    {
        std::cerr << "Exception: " << err.what() << std::endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <float.h>
#include <sstream>
#include <queue>

#include "reductions.h"
#include "vw.h"

namespace TOPK {
  typedef pair<float, v_array<char> > scored_example;

  struct compare_scored_examples
  {
    bool operator()(scored_example const& a, scored_example const& b) const
    { return a.first > b.first; }
  };

  struct topk{
    uint32_t B; //rec number
    priority_queue<scored_example, vector<scored_example>, compare_scored_examples > pr_queue;
    vw* all;
  };

  void print_result(int f, priority_queue<scored_example, vector<scored_example>, compare_scored_examples > &pr_queue)
  {
    if (f >= 0)
    {
      char temp[30];
      std::stringstream ss;
      scored_example tmp_example;
      while(!pr_queue.empty())
      {
        tmp_example = pr_queue.top();
        pr_queue.pop();
        sprintf(temp, "%f", tmp_example.first);
        ss << temp;
        ss << ' ';
        print_tag(ss, tmp_example.second);
        ss << ' ';
        ss << '\n';
      }
      ss << '\n';
      ssize_t len = ss.str().size();
#ifdef _WIN32
	  ssize_t t = _write(f, ss.str().c_str(), (unsigned int)len);
#else
	  ssize_t t = write(f, ss.str().c_str(), (unsigned int)len);
#endif
      if (t != len)
        cerr << "write error" << endl;
    }
  }

  void output_example(vw& all, topk& d, example& ec)
  {
    label_data& ld = ec.l.simple;

    if (ld.label != FLT_MAX)
      all.sd->weighted_labels += ld.label * ld.weight;
    all.sd->weighted_examples += ld.weight;
    all.sd->sum_loss += ec.loss;
    all.sd->sum_loss_since_last_dump += ec.loss;
    all.sd->total_features += ec.num_features;
    all.sd->example_number++;

    if (example_is_newline(ec))
      for (int* sink = all.final_prediction_sink.begin; sink != all.final_prediction_sink.end; sink++)
        TOPK::print_result(*sink, d.pr_queue);

    print_update(all, ec);
  }

  template <bool is_learn>
  void predict_or_learn(topk& d, LEARNER::base_learner& base, example& ec)
  {
    if (example_is_newline(ec)) return;//do not predict newline

    if (is_learn)
      base.learn(ec);
    else
      base.predict(ec);

    if(d.pr_queue.size() < d.B)
      d.pr_queue.push(make_pair(ec.pred.scalar, ec.tag));

    else if(d.pr_queue.top().first < ec.pred.scalar)
    {
      d.pr_queue.pop();
      d.pr_queue.push(make_pair(ec.pred.scalar, ec.tag));
    }
  }

  void finish_example(vw& all, topk& d, example& ec)
  {
    TOPK::output_example(all, d, ec);
    VW::finish_example(all, &ec);
  }

  LEARNER::base_learner* setup(vw& all)
  {
    new_options(all, "TOP K options")
      ("top", po::value<size_t>(), "top k recommendation");
    if(missing_required(all)) return NULL;

    topk& data = calloc_or_die<topk>();
    data.B = (uint32_t)all.vm["top"].as<size_t>();
    data.all = &all;

    LEARNER::learner<topk>& l = init_learner(&data, setup_base(all), predict_or_learn<true>,
					     predict_or_learn<false>);
    l.set_finish_example(finish_example);

    return make_base(l);
  }
}
<commit_msg>topk simplifications<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <sstream>
#include <queue>

#include "reductions.h"
#include "vw.h"

namespace TOPK {
  typedef pair<float, v_array<char> > scored_example;

  struct compare_scored_examples
  {
    bool operator()(scored_example const& a, scored_example const& b) const
    { return a.first > b.first; }
  };

  struct topk{
    uint32_t B; //rec number
    priority_queue<scored_example, vector<scored_example>, compare_scored_examples > pr_queue;
  };

  void print_result(int f, priority_queue<scored_example, vector<scored_example>, compare_scored_examples > &pr_queue)
  {
    if (f >= 0)
    {
      char temp[30];
      std::stringstream ss;
      scored_example tmp_example;
      while(!pr_queue.empty())
      {
        tmp_example = pr_queue.top();
        pr_queue.pop();
        sprintf(temp, "%f", tmp_example.first);
        ss << temp;
        ss << ' ';
        print_tag(ss, tmp_example.second);
        ss << ' ';
        ss << '\n';
      }
      ss << '\n';
      ssize_t len = ss.str().size();
#ifdef _WIN32
	  ssize_t t = _write(f, ss.str().c_str(), (unsigned int)len);
#else
	  ssize_t t = write(f, ss.str().c_str(), (unsigned int)len);
#endif
      if (t != len)
        cerr << "write error" << endl;
    }
  }

  void output_example(vw& all, topk& d, example& ec)
  {
    label_data& ld = ec.l.simple;

    if (ld.label != FLT_MAX)
      all.sd->weighted_labels += ld.label * ld.weight;
    all.sd->weighted_examples += ld.weight;
    all.sd->sum_loss += ec.loss;
    all.sd->sum_loss_since_last_dump += ec.loss;
    all.sd->total_features += ec.num_features;
    all.sd->example_number++;

    if (example_is_newline(ec))
      for (int* sink = all.final_prediction_sink.begin; sink != all.final_prediction_sink.end; sink++)
        TOPK::print_result(*sink, d.pr_queue);

    print_update(all, ec);
  }

  template <bool is_learn>
  void predict_or_learn(topk& d, LEARNER::base_learner& base, example& ec)
  {
    if (example_is_newline(ec)) return;//do not predict newline

    if (is_learn)
      base.learn(ec);
    else
      base.predict(ec);

    if(d.pr_queue.size() < d.B)
      d.pr_queue.push(make_pair(ec.pred.scalar, ec.tag));

    else if(d.pr_queue.top().first < ec.pred.scalar)
      {
	d.pr_queue.pop();
	d.pr_queue.push(make_pair(ec.pred.scalar, ec.tag));
      }
  }

  void finish_example(vw& all, topk& d, example& ec)
  {
    TOPK::output_example(all, d, ec);
    VW::finish_example(all, &ec);
  }

  LEARNER::base_learner* setup(vw& all)
  {
    new_options(all, "TOP K options")
      ("top", po::value<size_t>(), "top k recommendation");
    if(missing_required(all)) return NULL;

    topk& data = calloc_or_die<topk>();
    data.B = (uint32_t)all.vm["top"].as<size_t>();

    LEARNER::learner<topk>& l = init_learner(&data, setup_base(all), predict_or_learn<true>,
					     predict_or_learn<false>);
    l.set_finish_example(finish_example);

    return make_base(l);
  }
}
<|endoftext|>


<commit_before><commit_msg>src: reading/owner/onread/onconnection for tcp<commit_after><|endoftext|>


<commit_before><commit_msg>update uoj8581<commit_after><|endoftext|>


<commit_before>#include "apps_starter.h"

std::vector<job> apps_vect;			// Определение вектора запущенных программ
struct termios hos_tmode;			// настройки терминала для hos

void sighandler(int signo)
{
	if (signo == SIGTSTP) {

	}

	if (signo == SIGINT) {

	}
}

// Спящего процесса возобновление
void fg_job(job &j)
{
	int status;
	std::vector<job>::iterator it;

	// Терминальной группы главной установка
	j.running = true;
	tcsetpgrp(STDIN_FILENO, j.pid);

	// Спящий процесс будим мы
	kill(-j.pid, SIGCONT);
	waitpid(j.pid, &status, WUNTRACED);

	if(WIFSTOPPED(status)) {
		j.running = false;
		tcsetpgrp(STDIN_FILENO, getpid());
		tcgetattr(STDIN_FILENO, &j.tmode);
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);
	}

	// Если завершился процесс - удаляем из вектора процессов его
	if(WIFEXITED(status)) {
		tcsetpgrp(STDIN_FILENO, getpid());
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);
		for(it = apps_vect.begin() ; it < apps_vect.end(); ++it)
			if (it->pid == j.pid)
				apps_vect.erase(it);
	}
}

// Сигналов обработку определяем мы
void init_signals()
{
	signal(SIGINT, &sighandler);
	signal(SIGTSTP, &sighandler);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
}

// Фоновых процессов список отображаем мы
void list_process() {
	timeout(-1);

	std::vector <std::string>	apps_names;

	DLGSTR						apps_dlg	= {};

	unsigned int				maxX,
								maxY;

	int							key_pressed;

	getmaxyx(stdscr, maxY, maxX);

	apps_dlg.title			= "Background applications";
	apps_dlg.style			= RED_WIN;
	apps_dlg.xpos			= maxX / 2 - llength(apps_dlg.title) / 2;
	apps_dlg.ypos			= maxY / 2;
	apps_dlg.ymax			= maxY / 2;
	apps_dlg.border_menu	= true;

	// Не делаем ничего, вектор если пуст
	if(!apps_vect.empty()) {
		for (unsigned int	i	= 0; i < apps_vect.size(); i++) {
			apps_names.push_back(apps_vect[i].name);
		}

		key_pressed	= 0;

		while (key_pressed != 27) {
			menu_win(apps_dlg, apps_names);
			key_pressed	= getch();					// пользователя ввод обрабатываем мы

			switch (key_pressed) {
				case KEY_UP:	if (apps_dlg.selected != 0)
									apps_dlg.selected--;
								break;

				case KEY_DOWN:	if (apps_dlg.selected != apps_names.size())
									apps_dlg.selected++;
								break;

				case '\n':		// процесс спящий мы будим
								endwin();
								fg_job(apps_vect[apps_dlg.selected - 1]);
								init_display();
								init_color();
								return;
			}
		}
	}
}

int app_start(int number_of_app, char** argv) {
	std::string name_app	= configurator(APPS_FILE, str(number_of_app) + "_app_launcher", "", false);
	std::string path_to_dir	= configurator(APPS_FILE, str(number_of_app) + "_app_path", "", false);
	erase();
	endwin();

	int		status;
	pid_t	chpid	= fork();

	job j = {
		.name = name_app,
		.pid = chpid
	};

	j.running = true;

	// В запущенных процессов список процесс помещаем мы
	apps_vect.insert(apps_vect.end(), j);

	if (chpid == 0) {
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTTOU, SIG_IGN);
		tcsetpgrp(STDIN_FILENO, getpid());
		chdir(path_to_dir.c_str());
		setpgid(getpid(), getpid());			 	// Создаём группу процессов
		if (execl(name_app.c_str(), "", NULL) == -1) 	// parent process
			exit(0);
	} else {
		waitpid(chpid, &status,WUNTRACED);
		tcsetpgrp(STDIN_FILENO, getpid());
		tcgetattr(STDIN_FILENO, &j.tmode);
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);

		if (WIFSTOPPED(status)) {	/* Если пользователем процесс был остановлен */
			apps_vect.back().running = false;
		}

		if(WIFEXITED(status)) {
			apps_vect.pop_back();
		}

		init_display();
		init_color();
	}
	return 0;
}<commit_msg>Перевод на новое окно<commit_after>#include "apps_starter.h"

std::vector<job> apps_vect;			// Определение вектора запущенных программ
struct termios hos_tmode;			// настройки терминала для hos

void sighandler(int signo)
{
	if (signo == SIGTSTP) {

	}

	if (signo == SIGINT) {

	}
}

// Спящего процесса возобновление
void fg_job(job &j)
{
	int status;
	std::vector<job>::iterator it;

	// Терминальной группы главной установка
	j.running = true;
	tcsetpgrp(STDIN_FILENO, j.pid);

	// Спящий процесс будим мы
	kill(-j.pid, SIGCONT);
	waitpid(j.pid, &status, WUNTRACED);

	if(WIFSTOPPED(status)) {
		j.running = false;
		tcsetpgrp(STDIN_FILENO, getpid());
		tcgetattr(STDIN_FILENO, &j.tmode);
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);
	}

	// Если завершился процесс - удаляем из вектора процессов его
	if(WIFEXITED(status)) {
		tcsetpgrp(STDIN_FILENO, getpid());
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);
		for(it = apps_vect.begin() ; it < apps_vect.end(); ++it)
			if (it->pid == j.pid)
				apps_vect.erase(it);
	}
}

// Сигналов обработку определяем мы
void init_signals()
{
	signal(SIGINT, &sighandler);
	signal(SIGTSTP, &sighandler);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
}

// Фоновых процессов список отображаем мы
void list_process() {
	std::vector <std::string>	apps_names;

	Init_MENSTR(apps_menu);

	getmaxyx(stdscr, apps_menu.posY, apps_menu.posX);

	apps_menu.posX		= apps_menu.posX / 2 - 12;
	apps_menu.posY		= apps_menu.posY / 2;
	apps_menu.posXmax	= 25;

	// Не делаем ничего, вектор если пуст
	if(!apps_vect.empty()) {
		for (unsigned int	i	= 0; i < apps_vect.size(); i++) {
			apps_names.push_back(apps_vect[i].name);
		}

		unsigned int	selected	= menu_winV2(&apps_menu, "Background applications", apps_names, main_system_color);

		if (selected != 0) {	// процесс спящий мы будим
			endwin();
			fg_job(apps_vect[selected - 1]);
			init_display();
			init_color();
		}
	}
}

int app_start(int number_of_app, char** argv) {
	std::string name_app	= configurator(APPS_FILE, str(number_of_app) + "_app_launcher", "", false);
	std::string path_to_dir	= configurator(APPS_FILE, str(number_of_app) + "_app_path", "", false);
	erase();
	endwin();

	int		status;
	pid_t	chpid	= fork();

	job j = {
		.name = configurator(APPS_FILE, str(number_of_app) + "_app_package_name", "", false),
		.pid = chpid
	};

	j.running = true;

	// В запущенных процессов список процесс помещаем мы
	apps_vect.insert(apps_vect.end(), j);

	if (chpid == 0) {
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTTOU, SIG_IGN);
		tcsetpgrp(STDIN_FILENO, getpid());
		chdir(path_to_dir.c_str());
		setpgid(getpid(), getpid());			 	// Создаём группу процессов
		if (execl(name_app.c_str(), "", NULL) == -1) 	// parent process
			exit(0);
	} else {
		waitpid(chpid, &status,WUNTRACED);
		tcsetpgrp(STDIN_FILENO, getpid());
		tcgetattr(STDIN_FILENO, &j.tmode);
		tcsetattr(STDIN_FILENO, TCSADRAIN, &hos_tmode);

		if (WIFSTOPPED(status)) {	/* Если пользователем процесс был остановлен */
			apps_vect.back().running = false;
		}

		if(WIFEXITED(status)) {
			apps_vect.pop_back();
		}

		init_display();
		init_color();
	}
	return 0;
}<|endoftext|>


<commit_before>#include "config.h"

#ifdef CONFIG_GDK_PIXBUF_XLIB

#include "yimage.h"
#include "yxapp.h"
#include "ypixbuf.h"

extern "C" {
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
}

class YImageGDK: public YImage {
public:
    YImageGDK(int width, int height, GdkPixbuf *pixbuf): YImage(width, height) {
        fPixbuf = pixbuf;
    }
    virtual ~YImageGDK() {
        gdk_pixbuf_unref(fPixbuf);
    }
    virtual ref<YPixmap> renderToPixmap();
    virtual ref<YImage> scale(int width, int height);
    virtual void draw(Graphics &g, int dx, int dy);
    virtual void draw(Graphics &g, int x, int y, int w, int h, int dx, int dy);
    virtual void composite(Graphics &g, int x, int y, int w, int h, int dx, int dy);
    virtual bool valid() const { return fPixbuf != 0; }
private:
    GdkPixbuf *fPixbuf;
};

ref<YImage> YImage::create(int width, int height) {
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);
    if (pixbuf != NULL) {
        image.init(new YImageGDK(width, height, pixbuf));
    }
    return image;
}

ref<YImage> YImage::load(upath filename) {
    ref<YImage> image;
    GError *gerror = 0;
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(cstring(filename.path()).c_str(), &gerror);

    if (pixbuf != NULL) {
        image.init(new YImageGDK(gdk_pixbuf_get_width(pixbuf),
                                 gdk_pixbuf_get_height(pixbuf),
                                 pixbuf));
    }
    return image;
}

ref<YImage> YImageGDK::scale(int w, int h) {
    ref<YImage> image;
    GdkPixbuf *pixbuf = 0;
    bool alpha = gdk_pixbuf_get_has_alpha(fPixbuf);
#if 0
    pixbuf = gdk_pixbuf_scale_simple(fPixbuf,
                                     w, h,
                                     GDK_INTERP_BILINEAR);
#else
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, alpha, 8, w, h);

    pixbuf_scale(gdk_pixbuf_get_pixels(fPixbuf),
                 gdk_pixbuf_get_rowstride(fPixbuf),
                 gdk_pixbuf_get_width(fPixbuf),
                 gdk_pixbuf_get_height(fPixbuf),
                 gdk_pixbuf_get_pixels(pixbuf),
                 gdk_pixbuf_get_rowstride(pixbuf),
                 gdk_pixbuf_get_width(pixbuf),
                 gdk_pixbuf_get_height(pixbuf),
                 alpha);
#endif

    if (pixbuf != NULL) {
        image.init(new YImageGDK(w, h, pixbuf));
    }

    return image;
}

ref<YImage> YImage::createFromPixmap(ref<YPixmap> pixmap) {
    return createFromPixmapAndMask(pixmap->pixmap(),
                                   pixmap->mask(),
                                   pixmap->width(),
                                   pixmap->height());
}

ref<YImage> YImage::createFromPixmapAndMask(Pixmap pixmap, Pixmap mask,
                                            int width, int height)
{
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
                       width, height);

    if (pixbuf) {
        pixbuf =
            gdk_pixbuf_xlib_get_from_drawable(pixbuf,
                                              pixmap,
                                              xlib_rgb_get_cmap(),
                                              xlib_rgb_get_visual(),
                                              0, 0,
                                              0, 0,
                                              width,
                                              height);

        if (mask != None) {
            XImage *image = XGetImage(xapp->display(), mask,
                                      0, 0, width, height,
                                      AllPlanes, ZPixmap);
            guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);

            if (image) {
                //unsigned char *pix = image->data;
                for (int r = 0; r < height; r++) {
                    for (int c = 0; c < width; c++) {
                        unsigned int pix = XGetPixel(image, c, r);
                        pixels[c * 4 + 3] = pix ? 255 : 0;
                    }
                    pixels += gdk_pixbuf_get_rowstride(pixbuf);
                    //pix += image->bytes_per_line;
                }
                XDestroyImage(image);
            }
        }

        image.init(new YImageGDK(width,
                                 height,
                                 pixbuf));
    }
    return image;
}

ref<YImage> YImage::createFromIconProperty(long *prop_pixels,
                                           int width, int height)
{
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
                       width, height);

    if (!pixbuf)
        return null;

    guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);

    for (int r = 0; r < height; r++) {
        for (int c = 0; c < width; c++) {
            unsigned long pix =
                prop_pixels[c + r * width];
#warning "check if byteorder switching is needed"
            pixels[c * 4 + 2] = pix & 0xFF;
            pixels[c * 4 + 1] = (pix >> 8) & 0xFF;
            pixels[c * 4] = (pix >> 16) & 0xFF;
            pixels[c * 4 + 3] = (pix >> 24) & 0xFF;
        }
        pixels += gdk_pixbuf_get_rowstride(pixbuf);
    }
    image.init(new YImageGDK(width,
                             height,
                             pixbuf));
    return image;
}

ref<YImage> YImage::createFromPixmapAndMaskScaled(Pixmap pix, Pixmap mask,
                                                  int width, int height,
                                                  int nw, int nh)
{
    ref<YImage> image = createFromPixmapAndMask(pix, mask, width, height);
    if (image != null)
        image = image->scale(nw, nh);
    return image;
}

ref<YPixmap> YImageGDK::renderToPixmap() {
    Pixmap pixmap = None, mask = None;
    gdk_pixbuf_xlib_render_pixmap_and_mask(fPixbuf, &pixmap, &mask, 128);

    return createPixmap(pixmap, mask,
                        gdk_pixbuf_get_width(fPixbuf),
                        gdk_pixbuf_get_height(fPixbuf));
}

ref<YPixmap> YImage::createPixmap(Pixmap pixmap, Pixmap mask, int w, int h) {
    ref<YPixmap> n;

    n.init(new YPixmap(pixmap, mask, w, h));
    return n;
}

void YImageGDK::draw(Graphics &g, int dx, int dy) {
    gdk_pixbuf_xlib_render_to_drawable_alpha(fPixbuf, g.drawable(), //g.handleX(),
                                             0, 0, dx, dy, width(), height(),
                                             GDK_PIXBUF_ALPHA_BILEVEL, 128,
                                             XLIB_RGB_DITHER_NORMAL, 0, 0);
}

void YImageGDK::draw(Graphics &g, int x, int y, int w, int h, int dx, int dy) {
    gdk_pixbuf_xlib_render_to_drawable_alpha(fPixbuf, g.drawable(), //g.handleX(),
                                             x, y, dx, dy, w, h,
                                             GDK_PIXBUF_ALPHA_BILEVEL, 128,
                                             XLIB_RGB_DITHER_NORMAL, 0, 0);
}

void YImageGDK::composite(Graphics &g, int x, int y, int w, int h, int dx, int dy) {
    //msg("composite %d %d %d %d | %d %d", x, y, w, h, dx, dy);
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
    gdk_pixbuf_xlib_get_from_drawable(pixbuf,
                                      g.drawable(),
                                      xapp->colormap(),
                                      xapp->visual(),
                                      dx, dy, 0, 0, w, h);
    gdk_pixbuf_composite(fPixbuf, pixbuf,
                         0, 0, w, h,
                         -x, -y, 1.0, 1.0,
                         GDK_INTERP_BILINEAR, 255);
    gdk_pixbuf_xlib_render_to_drawable(pixbuf, g.drawable(), g.handleX(),
                                             0, 0, dx, dy, w, h,
//                                             GDK_PIXBUF_ALPHA_BILEVEL, 128,
                                             XLIB_RGB_DITHER_NONE, 0, 0);
    gdk_pixbuf_unref(pixbuf);
}

void image_init() {
    g_type_init();
    xlib_rgb_init(xapp->display(), ScreenOfDisplay(xapp->display(), xapp->screen()));
    gdk_pixbuf_xlib_init(xapp->display(), xapp->screen());
}

#endif
<commit_msg>always use compositing for image drawing<commit_after>#include "config.h"

#ifdef CONFIG_GDK_PIXBUF_XLIB

#include "yimage.h"
#include "yxapp.h"
#include "ypixbuf.h"

extern "C" {
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
}

class YImageGDK: public YImage {
public:
    YImageGDK(int width, int height, GdkPixbuf *pixbuf): YImage(width, height) {
        fPixbuf = pixbuf;
    }
    virtual ~YImageGDK() {
        gdk_pixbuf_unref(fPixbuf);
    }
    virtual ref<YPixmap> renderToPixmap();
    virtual ref<YImage> scale(int width, int height);
    virtual void draw(Graphics &g, int dx, int dy);
    virtual void draw(Graphics &g, int x, int y, int w, int h, int dx, int dy);
    virtual void composite(Graphics &g, int x, int y, int w, int h, int dx, int dy);
    virtual bool valid() const { return fPixbuf != 0; }
private:
    GdkPixbuf *fPixbuf;
};

ref<YImage> YImage::create(int width, int height) {
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);
    if (pixbuf != NULL) {
        image.init(new YImageGDK(width, height, pixbuf));
    }
    return image;
}

ref<YImage> YImage::load(upath filename) {
    ref<YImage> image;
    GError *gerror = 0;
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(cstring(filename.path()).c_str(), &gerror);

    if (pixbuf != NULL) {
        image.init(new YImageGDK(gdk_pixbuf_get_width(pixbuf),
                                 gdk_pixbuf_get_height(pixbuf),
                                 pixbuf));
    }
    return image;
}

ref<YImage> YImageGDK::scale(int w, int h) {
    ref<YImage> image;
    GdkPixbuf *pixbuf = 0;
    bool alpha = gdk_pixbuf_get_has_alpha(fPixbuf);
#if 0
    pixbuf = gdk_pixbuf_scale_simple(fPixbuf,
                                     w, h,
                                     GDK_INTERP_BILINEAR);
#else
    pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, alpha, 8, w, h);

    pixbuf_scale(gdk_pixbuf_get_pixels(fPixbuf),
                 gdk_pixbuf_get_rowstride(fPixbuf),
                 gdk_pixbuf_get_width(fPixbuf),
                 gdk_pixbuf_get_height(fPixbuf),
                 gdk_pixbuf_get_pixels(pixbuf),
                 gdk_pixbuf_get_rowstride(pixbuf),
                 gdk_pixbuf_get_width(pixbuf),
                 gdk_pixbuf_get_height(pixbuf),
                 alpha);
#endif

    if (pixbuf != NULL) {
        image.init(new YImageGDK(w, h, pixbuf));
    }

    return image;
}

ref<YImage> YImage::createFromPixmap(ref<YPixmap> pixmap) {
    return createFromPixmapAndMask(pixmap->pixmap(),
                                   pixmap->mask(),
                                   pixmap->width(),
                                   pixmap->height());
}

ref<YImage> YImage::createFromPixmapAndMask(Pixmap pixmap, Pixmap mask,
                                            int width, int height)
{
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
                       width, height);

    if (pixbuf) {
        pixbuf =
            gdk_pixbuf_xlib_get_from_drawable(pixbuf,
                                              pixmap,
                                              xlib_rgb_get_cmap(),
                                              xlib_rgb_get_visual(),
                                              0, 0,
                                              0, 0,
                                              width,
                                              height);

        if (mask != None) {
            XImage *image = XGetImage(xapp->display(), mask,
                                      0, 0, width, height,
                                      AllPlanes, ZPixmap);
            guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);

            if (image) {
                //unsigned char *pix = image->data;
                for (int r = 0; r < height; r++) {
                    for (int c = 0; c < width; c++) {
                        unsigned int pix = XGetPixel(image, c, r);
                        pixels[c * 4 + 3] = pix ? 255 : 0;
                    }
                    pixels += gdk_pixbuf_get_rowstride(pixbuf);
                    //pix += image->bytes_per_line;
                }
                XDestroyImage(image);
            }
        }

        image.init(new YImageGDK(width,
                                 height,
                                 pixbuf));
    }
    return image;
}

ref<YImage> YImage::createFromIconProperty(long *prop_pixels,
                                           int width, int height)
{
    ref<YImage> image;
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
                       width, height);

    if (!pixbuf)
        return null;

    guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);

    for (int r = 0; r < height; r++) {
        for (int c = 0; c < width; c++) {
            unsigned long pix =
                prop_pixels[c + r * width];
#warning "check if byteorder switching is needed"
            pixels[c * 4 + 2] = pix & 0xFF;
            pixels[c * 4 + 1] = (pix >> 8) & 0xFF;
            pixels[c * 4] = (pix >> 16) & 0xFF;
            pixels[c * 4 + 3] = (pix >> 24) & 0xFF;
        }
        pixels += gdk_pixbuf_get_rowstride(pixbuf);
    }
    image.init(new YImageGDK(width,
                             height,
                             pixbuf));
    return image;
}

ref<YImage> YImage::createFromPixmapAndMaskScaled(Pixmap pix, Pixmap mask,
                                                  int width, int height,
                                                  int nw, int nh)
{
    ref<YImage> image = createFromPixmapAndMask(pix, mask, width, height);
    if (image != null)
        image = image->scale(nw, nh);
    return image;
}

ref<YPixmap> YImageGDK::renderToPixmap() {
    Pixmap pixmap = None, mask = None;
    gdk_pixbuf_xlib_render_pixmap_and_mask(fPixbuf, &pixmap, &mask, 128);

    return createPixmap(pixmap, mask,
                        gdk_pixbuf_get_width(fPixbuf),
                        gdk_pixbuf_get_height(fPixbuf));
}

ref<YPixmap> YImage::createPixmap(Pixmap pixmap, Pixmap mask, int w, int h) {
    ref<YPixmap> n;

    n.init(new YPixmap(pixmap, mask, w, h));
    return n;
}

void YImageGDK::draw(Graphics &g, int dx, int dy) {
#if 1
    composite(g, 0, 0, width(), height(), dx, dy);
#else
    gdk_pixbuf_xlib_render_to_drawable_alpha(fPixbuf, g.drawable(), //g.handleX(),
                                             0, 0, dx, dy, width(), height(),
                                             GDK_PIXBUF_ALPHA_FULL,
                                             128,
                                             XLIB_RGB_DITHER_NORMAL, 0, 0);
#endif
}

void YImageGDK::draw(Graphics &g, int x, int y, int w, int h, int dx, int dy) {
#if 1
    composite(g, x, y, w, h, dx, dy);
#else
    gdk_pixbuf_xlib_render_to_drawable_alpha(fPixbuf, g.drawable(), //g.handleX(),
                                             x, y, dx, dy, w, h,
                                             GDK_PIXBUF_ALPHA_BILEVEL, 128,
                                             XLIB_RGB_DITHER_NORMAL, 0, 0);
#endif
}

void YImageGDK::composite(Graphics &g, int x, int y, int w, int h, int dx, int dy) {
    //msg("composite %d %d %d %d | %d %d", x, y, w, h, dx, dy);
    GdkPixbuf *pixbuf =
        gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
    gdk_pixbuf_xlib_get_from_drawable(pixbuf,
                                      g.drawable(),
                                      xapp->colormap(),
                                      xapp->visual(),
                                      dx, dy, 0, 0, w, h);
    gdk_pixbuf_composite(fPixbuf, pixbuf,
                         0, 0, w, h,
                         -x, -y, 1.0, 1.0,
                         GDK_INTERP_BILINEAR, 255);
    gdk_pixbuf_xlib_render_to_drawable(pixbuf, g.drawable(), g.handleX(),
                                             0, 0, dx, dy, w, h,
//                                             GDK_PIXBUF_ALPHA_BILEVEL, 128,
                                             XLIB_RGB_DITHER_NONE, 0, 0);
    gdk_pixbuf_unref(pixbuf);
}

void image_init() {
    g_type_init();
    xlib_rgb_init(xapp->display(), ScreenOfDisplay(xapp->display(), xapp->screen()));
    gdk_pixbuf_xlib_init(xapp->display(), xapp->screen());
}

#endif
<|endoftext|>


<commit_before>
#include "atList.h++"

atList::atList()
{
   // Initialize the doubly-linked list
   list_head = NULL;
   list_tail = NULL;
   num_entries = 0;

   // We haven't started traversing the list
   current_entry = NULL;
   next_entry = list_head;
}

atList::~atList()
{
   atListEntry *  current;
   atListEntry *  old;

   // Go through the list and delete the items and entries
   current = list_head;
   while (current != NULL)
   {
      // Delete the item if it exists
      if (current->item != NULL)
         delete current->item;

      // Save a pointer to this entry
      old = current;

      // Move to the next entry
      current = current->next;

      // Free the old one of which we saved a pointer
      free(old);
   }
}

u_long atList::getNumEntries()
{
   return num_entries;
}

bool atList::addEntry(atItem * item)
{
   atListEntry   *newEntry;

   // Create a new entry for this item in the list
   newEntry = (atListEntry *) calloc(1, sizeof(atListEntry));
   if (newEntry == NULL)
   {
      // We failed to allocate the memory so tell user and return a failure
      notify(AT_WARN, "Unable to allocate memory in List.\n");
      return false;
   }
   else
   {
      // Set the fields of the new entry
      newEntry->item = item;
      newEntry->next = NULL;
      newEntry->previous = NULL;

      // Add the new entry to the end of the list
      if (list_head == NULL)
      {
         // Adding only entry in list
         list_head = newEntry;
         list_tail = newEntry;
      }
      else
      {
         // Just adding it to end of list
         list_tail->next = newEntry;
         newEntry->previous = list_tail;
         list_tail = newEntry;
      }

      // Increment the number of entries since we just added one
      num_entries++;

      // Return success
      return true;
   }
}

bool atList::insertEntry(atItem * item)
{
   atListEntry *   newEntry;

   // If we don't have a current node but we do have nodes, return a failure
   // since we do not know where to insert the node
   if ( (current_entry == NULL) && (list_head != NULL) )
      return false;
   else
   {
      // Create a new entry for this item in the list
      newEntry = (atListEntry *) calloc(1, sizeof(atListEntry));
      if (newEntry == NULL)
      {
         // We failed to allocate the memory so tell user and return a failure
         notify(AT_WARN, "Unable to allocate memory in List.\n");
         return false;
      }
      else
      {
         // Set the fields of the new entry
         newEntry->item = item;
         newEntry->next = NULL;
         newEntry->previous = NULL;
      }

      // Insert the entry *before* the current node
      if (list_head == NULL)
      {
         // We are inserting into an empty list
         list_head = newEntry;
         list_tail = newEntry;
      }
      else if (current_entry->previous == NULL)
      {
         // We are inserting in front of the first node so update the head
         current_entry->previous = newEntry;
         newEntry->next = current_entry;
         list_head = newEntry;
      }
      else
      {
         // We are inserting at the middle of the list (because we insert
         // *before*, we never have the case at the very end of the list)
         current_entry->previous->next = newEntry;
         newEntry->previous = current_entry->previous;
         current_entry->previous = newEntry;
         newEntry->next = current_entry;
      }

      // We succeeded
      return true;
   }
}

bool atList::removeCurrentEntry()
{
   atListEntry *  old;

   // If we don't have a current node, return a failure
   if (current_entry == NULL)
      return false;
   else
   {
      // Take the node out of the list (but handle special case of being
      // at the first node in the list)
      if (current_entry->previous == NULL)
      {
         // We are removing the first node so move the head pointer
         list_head = current_entry->next;

         // Now we need to fix the back pointer (previous pointer) of the
         // new first node but only if it exists of course (i.e. make sure
         // we didn't just remove the ONLY node)
         if (current_entry->next != NULL)
         {
            // We have another node so set its "previous" pointer to NULL
            // so it knows it's the front of the list
            current_entry->next->previous = NULL;
         }
         else
         {
            // We're also removing the last node (must be the only node) so
            // we need to fix the tail pointer
            list_tail = NULL;
         }
      }
      else
      {
         // Otherwise, we are removing a node that isn't first so the
         // general approach works (put in the new forward link and
         // and then fix the back link if we have a node (i.e. we aren't
         // removing the last node in the list)
         current_entry->previous->next = current_entry->next;
         if (current_entry->next != NULL)
            current_entry->next->previous = current_entry->previous;
      }

      // Save a pointer to the structure holding this item
      old = current_entry;

      // Check for head and tail issues for the "current entry"
      if (current_entry->previous == NULL)
      {
         // We removed the first node but the head is already okay

         // But it could be the only node too
         if (current_entry->next == NULL)
            list_tail = NULL;

         // Set the traversals
         next_entry = list_head;
         current_entry = NULL;
      }
      else if (current_entry->next == NULL)
      {
         // We removed the last node so fix the tail and set current and
         // next as being done with the list
         list_tail = current_entry->previous;
         current_entry = NULL;
         next_entry = NULL;
      }
      else
      {
         // We're removing a node in the middle
         next_entry = current_entry->next;
         current_entry = NULL;
      }

      // Free up the structure from the list
      free(old);

      // Remove one from our counter since we just took out a node
      num_entries--;

      // Return success
      return true;
   }
}

bool atList::removeAllEntries()
{
   // We'll do this by calling removeCurrentEntry() for each entry in
   // the list (since we're removing all entries, it won't matter that
   // we're messing with the current_entry pointer)
   while (list_head != NULL)
   {
       current_entry = list_head;
       removeCurrentEntry();
   }

   // Set traversal pointers
   current_entry = NULL;
   next_entry = NULL;

   // Return success
   return true;
}

atItem * atList::getFirstEntry()
{
   // Go to the first node (if it exists)
   current_entry = list_head;
   if (list_head != NULL)
      next_entry = list_head->next;
   else
      next_entry = NULL;

   // If we have a first node, return the item stored in it
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getNextEntry()
{
   // If there is a next node, move on and return it
   if (next_entry != NULL)
   {
      // Advance
      current_entry = next_entry;
      next_entry = current_entry->next;

      // Return the item
      return current_entry->item;
   }
   else
      return NULL;
}

atItem * atList::getPreviousEntry()
{
   // If we aren't at the beginning of the list, go to the previous node
   if (current_entry != NULL)
      current_entry = current_entry->previous;

   // If we have a new node, return its item
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getLastEntry()
{
   // Go to the last node (if it exists)
   current_entry = list_tail;
   next_entry = NULL;

   // If we have a first node, return the item stored in it
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getNthEntry(u_long n)
{
   u_long count;

   // Walk the list until we reach the n'th element
   count = 0;
   getFirstEntry();
   while ((count < n) && (current_entry != NULL))
   {
       // Increment the count
       count++;

       // Advance the current entry pointer
       getNextEntry();
   }

   // If the current_entry is NULL (the index is greater than the number
   // of elements in the list), return NULL
   if (current_entry == NULL)
      return NULL;

   // Otherwise, return the item at the given list entry
   return current_entry->item;
}

atItem * atList::findEntry(atItem * item)
{
   atItem *currentItem;

   // Walk the list until we find an item in the list that matches the given
   // item (according to the item's equals() method)
   currentItem = getFirstEntry();
   while ((currentItem != NULL) && (!currentItem->equals(item)))
       currentItem = getNextEntry();

   // Return the item we found, or NULL if we didn't find it
   return currentItem;
}
<commit_msg>Fix bug where insertEntry() was not incrementing the counter of the number of entries.<commit_after>
#include "atList.h++"

atList::atList()
{
   // Initialize the doubly-linked list
   list_head = NULL;
   list_tail = NULL;
   num_entries = 0;

   // We haven't started traversing the list
   current_entry = NULL;
   next_entry = list_head;
}

atList::~atList()
{
   atListEntry *  current;
   atListEntry *  old;

   // Go through the list and delete the items and entries
   current = list_head;
   while (current != NULL)
   {
      // Delete the item if it exists
      if (current->item != NULL)
         delete current->item;

      // Save a pointer to this entry
      old = current;

      // Move to the next entry
      current = current->next;

      // Free the old one of which we saved a pointer
      free(old);
   }
}

u_long atList::getNumEntries()
{
   return num_entries;
}

bool atList::addEntry(atItem * item)
{
   atListEntry   *newEntry;

   // Create a new entry for this item in the list
   newEntry = (atListEntry *) calloc(1, sizeof(atListEntry));
   if (newEntry == NULL)
   {
      // We failed to allocate the memory so tell user and return a failure
      notify(AT_WARN, "Unable to allocate memory in List.\n");
      return false;
   }
   else
   {
      // Set the fields of the new entry
      newEntry->item = item;
      newEntry->next = NULL;
      newEntry->previous = NULL;

      // Add the new entry to the end of the list
      if (list_head == NULL)
      {
         // Adding only entry in list
         list_head = newEntry;
         list_tail = newEntry;
      }
      else
      {
         // Just adding it to end of list
         list_tail->next = newEntry;
         newEntry->previous = list_tail;
         list_tail = newEntry;
      }

      // Increment the number of entries since we just added one
      num_entries++;

      // Return success
      return true;
   }
}

bool atList::insertEntry(atItem * item)
{
   atListEntry *   newEntry;

   // If we don't have a current node but we do have nodes, return a failure
   // since we do not know where to insert the node
   if ( (current_entry == NULL) && (list_head != NULL) )
      return false;
   else
   {
      // Create a new entry for this item in the list
      newEntry = (atListEntry *) calloc(1, sizeof(atListEntry));
      if (newEntry == NULL)
      {
         // We failed to allocate the memory so tell user and return a failure
         notify(AT_WARN, "Unable to allocate memory in List.\n");
         return false;
      }
      else
      {
         // Set the fields of the new entry
         newEntry->item = item;
         newEntry->next = NULL;
         newEntry->previous = NULL;
      }

      // Insert the entry *before* the current node
      if (list_head == NULL)
      {
         // We are inserting into an empty list
         list_head = newEntry;
         list_tail = newEntry;
      }
      else if (current_entry->previous == NULL)
      {
         // We are inserting in front of the first node so update the head
         current_entry->previous = newEntry;
         newEntry->next = current_entry;
         list_head = newEntry;
      }
      else
      {
         // We are inserting at the middle of the list (because we insert
         // *before*, we never have the case at the very end of the list)
         current_entry->previous->next = newEntry;
         newEntry->previous = current_entry->previous;
         current_entry->previous = newEntry;
         newEntry->next = current_entry;
      }

      // Increment the number of entries since we just added one
      num_entries++;

      // We succeeded
      return true;
   }
}

bool atList::removeCurrentEntry()
{
   atListEntry *  old;

   // If we don't have a current node, return a failure
   if (current_entry == NULL)
      return false;
   else
   {
      // Take the node out of the list (but handle special case of being
      // at the first node in the list)
      if (current_entry->previous == NULL)
      {
         // We are removing the first node so move the head pointer
         list_head = current_entry->next;

         // Now we need to fix the back pointer (previous pointer) of the
         // new first node but only if it exists of course (i.e. make sure
         // we didn't just remove the ONLY node)
         if (current_entry->next != NULL)
         {
            // We have another node so set its "previous" pointer to NULL
            // so it knows it's the front of the list
            current_entry->next->previous = NULL;
         }
         else
         {
            // We're also removing the last node (must be the only node) so
            // we need to fix the tail pointer
            list_tail = NULL;
         }
      }
      else
      {
         // Otherwise, we are removing a node that isn't first so the
         // general approach works (put in the new forward link and
         // and then fix the back link if we have a node (i.e. we aren't
         // removing the last node in the list)
         current_entry->previous->next = current_entry->next;
         if (current_entry->next != NULL)
            current_entry->next->previous = current_entry->previous;
      }

      // Save a pointer to the structure holding this item
      old = current_entry;

      // Check for head and tail issues for the "current entry"
      if (current_entry->previous == NULL)
      {
         // We removed the first node but the head is already okay

         // But it could be the only node too
         if (current_entry->next == NULL)
            list_tail = NULL;

         // Set the traversals
         next_entry = list_head;
         current_entry = NULL;
      }
      else if (current_entry->next == NULL)
      {
         // We removed the last node so fix the tail and set current and
         // next as being done with the list
         list_tail = current_entry->previous;
         current_entry = NULL;
         next_entry = NULL;
      }
      else
      {
         // We're removing a node in the middle
         next_entry = current_entry->next;
         current_entry = NULL;
      }

      // Free up the structure from the list
      free(old);

      // Remove one from our counter since we just took out a node
      num_entries--;

      // Return success
      return true;
   }
}

bool atList::removeAllEntries()
{
   // We'll do this by calling removeCurrentEntry() for each entry in
   // the list (since we're removing all entries, it won't matter that
   // we're messing with the current_entry pointer)
   while (list_head != NULL)
   {
       current_entry = list_head;
       removeCurrentEntry();
   }

   // Set traversal pointers
   current_entry = NULL;
   next_entry = NULL;

   // Return success
   return true;
}

atItem * atList::getFirstEntry()
{
   // Go to the first node (if it exists)
   current_entry = list_head;
   if (list_head != NULL)
      next_entry = list_head->next;
   else
      next_entry = NULL;

   // If we have a first node, return the item stored in it
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getNextEntry()
{
   // If there is a next node, move on and return it
   if (next_entry != NULL)
   {
      // Advance
      current_entry = next_entry;
      next_entry = current_entry->next;

      // Return the item
      return current_entry->item;
   }
   else
      return NULL;
}

atItem * atList::getPreviousEntry()
{
   // If we aren't at the beginning of the list, go to the previous node
   if (current_entry != NULL)
      current_entry = current_entry->previous;

   // If we have a new node, return its item
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getLastEntry()
{
   // Go to the last node (if it exists)
   current_entry = list_tail;
   next_entry = NULL;

   // If we have a first node, return the item stored in it
   if (current_entry != NULL)
      return current_entry->item;
   else
      return NULL;
}

atItem * atList::getNthEntry(u_long n)
{
   u_long count;

   // Walk the list until we reach the n'th element
   count = 0;
   getFirstEntry();
   while ((count < n) && (current_entry != NULL))
   {
       // Increment the count
       count++;

       // Advance the current entry pointer
       getNextEntry();
   }

   // If the current_entry is NULL (the index is greater than the number
   // of elements in the list), return NULL
   if (current_entry == NULL)
      return NULL;

   // Otherwise, return the item at the given list entry
   return current_entry->item;
}

atItem * atList::findEntry(atItem * item)
{
   atItem *currentItem;

   // Walk the list until we find an item in the list that matches the given
   // item (according to the item's equals() method)
   currentItem = getFirstEntry();
   while ((currentItem != NULL) && (!currentItem->equals(item)))
       currentItem = getNextEntry();

   // Return the item we found, or NULL if we didn't find it
   return currentItem;
}
<|endoftext|>


<commit_before><commit_msg>HasteMonster-wands now IDs on hit<commit_after><|endoftext|>


<commit_before>#include "cap2.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Cap2 w;
    w.show();

    return a.exec();
}
<commit_msg>Delete main.cpp<commit_after><|endoftext|>