text:
//Copyright (c) 2013 Singapore-MIT Alliance for Research and Technology
//Licensed under the terms of the MIT License, as described in the file:
//   license.txt   (http://opensource.org/licenses/MIT)

#pragma once
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/unordered_map.hpp>
#include "soci/soci.h"
#include "database/DB_Connection.hpp"
#include "util/LangHelpers.hpp"
#include "I_Dao.hpp"

namespace
{
/**
 * Visitor that will bind an variant value into an sql statement
 */
class ParamBinder: public boost::static_visitor<>
{
public:
    ParamBinder(soci::details::prepare_temp_type& statement) :
            statement(statement)
    {
    }

    template<typename T>
    void operator()(const T& val) const
    {
        statement, soci::use(val);
    }

    soci::details::prepare_temp_type& statement;
};

// POSTGRES dependent. Needs to be fixed.
const std::string DB_RETURNING_CLAUSE = "RETURNING";
const std::string DB_RETURNING_ALL_CLAUSE = " " + DB_RETURNING_CLAUSE + " * ";
}

namespace sim_mob
{

namespace db
{
typedef soci::row Row;
typedef soci::rowset<Row> ResultSet;

/**
 * Represents an Abstract implementation of Data Access Object for
 * SQL databases to a given template entity.
 *
 * Example:
 *     DB Table: Person
 *     Entity on System: Person
 *     Dao on System: PersonDao : AbstractDao<Person>
 *
 * Each entity *must* provide two main things:
 * Mandatory:
 *  - Empty constructor.
 *
 * Optional:
 *  - Operator<< defined
 *  - Friendship to the concrete Dao. (nice to have)
 *
 * Each DAO implementation *must* provide the following things:
 * Mandatory:
 *  - override fromRow() to convert SELECT statements to Entities.
 *  - override toRow() to convert data for CRUD statements.
 *  - Default queries:
 *      defaultQueries[INSERT] = "INSERT.....";
 *      defaultQueries[UPDATE] = "UPDATE.....";
 *      defaultQueries[DELETE] = "DELETE.....";
 *      defaultQueries[GET_ALL] = "SELECT * FROM.....";
 *      defaultQueries[GET_BY_ID] = SELECT * FROM..WHERE..";
 * NOTE: all parameters values for prepared statements are used like
 *       "field = :myfield"
 *
 *
 * Attention: The given connection is not managed by DAO implementation.
 * This implementation is not thread-safe.
 *
 * \author Pedro Gandola
 *
 */
template<typename T> class SqlAbstractDao: public I_Dao<T>
{
public:

    SqlAbstractDao(DB_Connection& connection, const std::string& _tableName, const std::string& insertQuery, const std::string& updateQuery,
            const std::string& deleteQuery, const std::string& getAllQuery, const std::string& getByIdQuery) :
            connection(connection), tableName(_tableName)
    {
        std::string str;

        str = connection.getSchema();

        tableName = str + _tableName;
        defaultQueries[INSERT] = insertQuery;
        defaultQueries[UPDATE] = updateQuery;
        defaultQueries[DELETE] = deleteQuery;
        defaultQueries[GET_ALL] = getAllQuery;
        defaultQueries[GET_BY_ID] = getByIdQuery;
    }

    virtual ~SqlAbstractDao()
    {
    }

    virtual T& insert(T& entity, bool returning = false)
    {
        if (isConnected())
        {
            // Get data to insert.
            Parameters params;
            toRow(entity, params, false);

            Transaction tr(connection.getSession<soci::session>());
            Statement query(connection.getSession<soci::session>());
            //append returning clause.
            //Attention: this is only prepared for POSTGRES.
            std::string upperQuery = boost::to_upper_copy(defaultQueries[INSERT]);

            if (returning)
            {
                size_t found = upperQuery.rfind(DB_RETURNING_CLAUSE);
                if (found == std::string::npos)
                {
                    upperQuery += DB_RETURNING_ALL_CLAUSE;
                }
            }

            // prepare statement.
            prepareStatement(upperQuery, params, query);
            //TODO: POSTGRES ONLY for now
            //execute and return data if (RETURNING clause is defined)
            ResultSet rs(query);

            if (returning)
            {
                ResultSet::const_iterator it = rs.begin();
                if (it != rs.end())
                {
                    fromRow((*it), entity);
                }
            }
            tr.commit();
        }
        return entity;
    }

    virtual T& insertViaQuery(T& entity, std::string insertQuery, bool returning = false)
    {
        if (isConnected())
        {
            // Get data to insert.
            Parameters params;
            toRow(entity, params, false);

            Transaction tr(connection.getSession<soci::session>());
            Statement query(connection.getSession<soci::session>());
            //append returning clause.
            //Attention: this is only prepared for POSTGRES.
            std::string upperQuery = boost::to_upper_copy(insertQuery);

            if (returning)
            {
                size_t found = upperQuery.rfind(DB_RETURNING_CLAUSE);
                if (found == std::string::npos)
                {
                    upperQuery += DB_RETURNING_ALL_CLAUSE;
                }
            }

            // prepare statement.
            prepareStatement(upperQuery, params, query);
            //TODO: POSTGRES ONLY for now
            //execute and return data if (RETURNING clause is defined)
            ResultSet rs(query);

            if (returning)
            {
                ResultSet::const_iterator it = rs.begin();
                if (it != rs.end())
                {
                    fromRow((*it), entity);
                }
            }
            tr.commit();
        }
        return entity;
    }

    //run a given query with given params
    virtual T& executeQueryWithParams(T& entity, std::string insertQuery, const Parameters& params,bool returning = false)
        {
            if (isConnected())
            {

                Transaction tr(connection.getSession<soci::session>());
                Statement query(connection.getSession<soci::session>());
                //append returning clause.
                //Attention: this is only prepared for POSTGRES.
                std::string upperQuery = boost::to_upper_copy(insertQuery);

                if (returning)
                {
                    size_t found = upperQuery.rfind(DB_RETURNING_CLAUSE);
                    if (found == std::string::npos)
                    {
                        upperQuery += DB_RETURNING_ALL_CLAUSE;
                    }
                }

                // prepare statement.
                prepareStatement(upperQuery, params, query);
                //TODO: POSTGRES ONLY for now
                //execute and return data if (RETURNING clause is defined)
                ResultSet rs(query);

                if (returning)
                {
                    ResultSet::const_iterator it = rs.begin();
                    if (it != rs.end())
                    {
                        fromRow((*it), entity);
                    }
                }
                tr.commit();
            }
            return entity;
        }

    virtual bool update(T& entity)
    {
        if (isConnected())
        {
            Transaction tr(connection.getSession<soci::session>());
            Statement query(connection.getSession<soci::session>());
            // Get data to insert.
            Parameters params;
            toRow(entity, params, true);
            // prepare statement.
            prepareStatement(defaultQueries[UPDATE], params, query);
            ResultSet rs(query);
            tr.commit();
            return true;
        }
        return false;
    }

    virtual bool erase(const Parameters& params)
    {
        if (isConnected())
        {
            Transaction tr(connection.getSession<soci::session>());
            Statement query(connection.getSession<soci::session>());
            // prepare statement.
            prepareStatement(defaultQueries[DELETE], params, query);
            //execute query.
            ResultSet rs(query);
            tr.commit();
            return true;
        }
        return false;
    }

    virtual bool getById(const Parameters& ids, T& outParam)
    {
        return getByValues(defaultQueries[GET_BY_ID], ids, outParam);
    }

    virtual bool getAll(std::vector<T>& outList)
    {
        return getByValues(defaultQueries[GET_ALL], EMPTY_PARAMS, outList);
    }

    virtual bool getAll(std::vector<T*>& outList)
    {
        return getByValues(defaultQueries[GET_ALL], EMPTY_PARAMS, outList);
    }

    template<typename K, typename F>
    bool getAll(boost::unordered_map<K, T>& outMap, F getter)
    {
        return getByValues(defaultQueries[GET_ALL], EMPTY_PARAMS, outMap, getter);
    }

    template<typename K, typename F>
    bool getAll(boost::unordered_map<K, T*>& outMap, F getter)
    {
        return getByValues(defaultQueries[GET_ALL], EMPTY_PARAMS, outMap, getter);
    }

    /*
     * execute a given query
     * @param query to be executed query
     * @param outList gives the result of the query
     */
    virtual bool getByQuery(std::string query, std::vector<T*>& outList)
    {
        return getByValues(query, EMPTY_PARAMS, outList);
    }

    /*
     * execute a given query with given parameters(ids)
     * @param query to be executed query
     * @param outList gives the result of the query
     */
    virtual bool getByQueryId(std::string query, const Parameters& ids,std::vector<T*>& outList)
    {
        return getByValues(query, ids, outList);
    }

    bool executeQuery(std::string queryStr)
    {
        if (isConnected())
                {
                    Transaction tr(connection.getSession<soci::session>());
                    Statement query(connection.getSession<soci::session>());
                    // prepare statement.
                    prepareStatement(queryStr, EMPTY_PARAMS, query);
                    //execute query.
                    ResultSet rs(query);
                    tr.commit();
                    return true;
                }
                return false;
    }

protected:
    // Protected types

    /**
     * Converts a given row into a T type.
     * @param result result row.
     * @param outParam (Out parameter) to receive data from row.
     */
    virtual void fromRow(Row& result, T& outParam)
    {
    }

    /**
     * Converts the given T data into a Parameter list to create a row.
     * @param data to create a new row.
     * @param outParams Parameter list that will receive the data.
     * @param update tells you if it is an update or an insert.
     */
    virtual void toRow(T& data, Parameters& outParams, bool update)
    {
    }

    /**
     * Enum for default queries.
     */
    enum DefaultQuery
    {
        INSERT = 0, UPDATE, DELETE, GET_ALL, GET_BY_ID, NUM_QUERIES
    };

    typedef soci::details::prepare_temp_type Statement;
    typedef soci::transaction Transaction;

protected:
    // methods

    /**
     * Tells we DAO has connection to the database.
     * @return
     */
    bool isConnected()
    {
        return (connection.isConnected());
    }

    /**
     * Helper function that allows get a list of
     * Entity objects (vector<V>) by given params.
     * The output will be assigned on outParam using the *fromRow*.
     * @param queryStr query string.
     * @param params to filter the query (to put on Where clause).
     * @param outParam to fill with retrieved objects.
     * @param getter to get the object key to insert on map.
     * @return true if some value was returned, false otherwise.
     */
    template<typename V, typename F>
    bool getByValues(const std::string& queryStr, const Parameters& params, V& outParam, F getter)
    {
        bool hasValues = false;
        if (isConnected())
        {
            Statement query(connection.getSession<soci::session>());
            prepareStatement(queryStr, params, query);
            ResultSet rs(query);
            ResultSet::const_iterator it = rs.begin();
            for (it; it != rs.end(); ++it)
            {
                appendRow((*it), outParam, getter);
                hasValues = true;
            }
        }
        return hasValues;
    }

    /**
     * Helper function that allows get a list of
     * Entity objects (vector<V>) by given params.
     * The output will be assigned on outParam using the *fromRow*.
     * @param queryStr query string.
     * @param params to filter the query (to put on Where clause).
     * @param outParam to fill with retrieved objects.
     * @return true if some value was returned, false otherwise.
     */
    template<typename V>
    bool getByValues(const std::string& queryStr, const Parameters& params, V& outParam)
    {
        bool hasValues = false;
        if (isConnected())
        {
            Statement query(connection.getSession<soci::session>());
            prepareStatement(queryStr, params, query);
            ResultSet rs(query);
            ResultSet::const_iterator it = rs.begin();
            for (it; it != rs.end(); ++it)
            {
                appendRow((*it), outParam);
                hasValues = true;
            }
        }
        return hasValues;
    }

    /**
     * Helper function to prepare the given statement.
     * @param queryStr query string.
     * @param params to put on the statement.
     * @param outParam out statement.
     */
    void prepareStatement(const std::string& queryStr, const Parameters& params, Statement& outParam)
    {
        outParam << queryStr;
        ParamBinder paramBinder(outParam);
        Parameters::const_iterator it = params.begin();
        for (it; it != params.end(); ++it)
        {
            boost::apply_visitor(paramBinder, *it);
        }
    }

private:

    /**
     * Append row to the given object.
     * @param row to create the object.
     * @param list to fill.
     */
    void appendRow(Row& row, T& obj)
    {
        fromRow(row, obj);
    }

    /**
     * Append row using dynamic memory.
     * @param row to create the object.
     * @param list to fill.
     */
    void appendRow(Row& row, std::vector<T*>& list)
    {
        T* model = new T();
        fromRow(row, *model);
        list.push_back(model);
    }

    /**
     * Append row using automatic memory.
     * @param row to create the object.
     * @param list to fill.
     */
    void appendRow(Row& row, std::vector<T>& list)
    {
        T model;
        fromRow(row, model);
        list.push_back(model);
    }

    /**
     * Append row using automatic memory.
     * @param row to create the object.
     * @param map to fill.
     * @param getter to get the key.
     */
    template<typename K, typename F>
    void appendRow(Row& row, boost::unordered_map<K, T>& map, F getter)
    {
        T model;
        fromRow(row, model);
        map.insert(std::make_pair(((model).*getter)(), model));
    }

    /**
     * Append row using dynamic memory.
     * @param row to create the object.
     * @param map to fill.
     * @param getter to get the key.
     */
    template<typename K, typename F>
    void appendRow(Row& row, boost::unordered_map<K, T*>& map, F getter)
    {
        T* model = new T();
        fromRow(row, *model);
        map.insert(std::make_pair((model->*getter)(), model));
    }

protected:
    DB_Connection& connection;
    std::string tableName;
    std::string defaultQueries[NUM_QUERIES + 1];
};
}
}


text:
//==================================================================================================
/*!
  @file

    @copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_MAX_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_MAX_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

  /*!

    @ingroup group-arithmetic
    This function object computes the largest of its parameter.

    @par Header <boost/simd/function/max.hpp>

    @par Notes
    For any given value @c x and @c y of type @c T:

    Using `max(x, y)` is similar to `(x > y) ? x : y` which is the standard behaviour.

    With this definition max(x, @ref Nan) should return x...

    On some systems the intrinsic used returns Nan as soon x or y is a nan.
    So the real definition of our max function must add: but if y is Nan the result is system dependent.

    This can be corrected using the pedantic_ decorator that ensures the standard behaviour at a cost.

    @par Decorators

     - pedantic_ ensures the standard behaviour.
     - std_ call std::max.

    @see min,  maxnum, maxnummag, maxmag

    @par Example:

      @snippet max.cpp max

    @par Possible output:

      @snippet max.txt max

  **/
  Value max(Value const& x, Value const& y);
} }
#endif

#include <boost/simd/function/scalar/max.hpp>
#include <boost/simd/function/simd/max.hpp>

#endif

ext: hpp

max_stars_repo_name: SylvainCorlay/pythran

max_issues_repo_name: SylvainCorlay/pythran

max_forks_repo_name: SylvainCorlay/pythran


text:
/***********************************************************************/
/* DecodeStream.cpp                                                    */
/* Author: James Weaver and Galen Reich                                */
/* This version July 2020                                              */
/*                                                                     */
/* Reads compressed stream in                                          */
/* Decompresses image using VC-2                                       */
/* Writes image data out to a planar file.                             */
/* It is not necessarily complet nor korrect.                          */
/* Copyright (c) BBC 2011-2020 -- For license see the LICENSE file     */
/***********************************************************************/

const char version[] = __DATE__ " @ " __TIME__ ;
const char summary[] = "Decodes a VC-2 stream to an uncompressed planar file";
const char description[] = "\
This program decodes SMPTE VC-2 stream data to regenerate an image sequence.\n\
Its primary output is the decoded image sequence. However it may produce alternative outputs which are:\n\
  1 the wavelet transform of the decoded output (inverse quantised wavelet coefficients)\n\
  2 the quantised wavelet coefficients\n\
  3 the quantisation indices used for each slice\n\
  4 the decoded sequence\n\
Input is a VC-2 stream.\n\
Output (where appropriate) are in planar format (4:4:4, 4:2:2, 4:2:0).\n\
There can be 1 to 4 bytes per sample and the data is left (MSB) justified.\n\
Data is assumed offset binary (which is fine for both YCbCr or RGB).\n\
\n\
Example: DecodeStream -v inFileName outFileName";
const char* details[] = {version, summary, description};

#include <cstdlib> //for EXIT_SUCCESS, EXIT_FAILURE, atoi
#include <stdexcept> //For standard logic errors
#include <iostream> //For cin, cout, cerr
#include <string>
#include <fstream>
#include <cstdio> // for perror
#include <boost/scoped_ptr.hpp>
#include <map>

#include "DecodeParams.h"
#include "Arrays.h"
#include "Slices.h"
#include "Picture.h"
#include "Frame.h"
#include "Quantisation.h"
#include "WaveletTransform.h"
#include "Utils.h"
#include "DataUnit.h"
#include "VLC.h"

using std::cout;
using std::cin;
using std::cerr;
using std::clog;
using std::endl;
using std::string;
using std::filebuf;
using std::streambuf;
using std::ios_base;
using std::istream;
using std::ostream;

struct FragmentedPictureData {
  FragmentedPictureData (const PictureFormat& pictureFormat, int waveletDepth,
                         int ySlices, int xSlices, int sp, int sss,
                         const Array1D &qm,
                         int h, int w, ColourFormat cf)
    : slices(pictureFormat, waveletDepth,
             ySlices, xSlices)
    , qMatrix(qm)
    , picFormat(h, w, cf)
    , slice_prefix(sp)
    , slice_size_scalar(sss)
    , slice_bytes()
    , slices_needed(xSlices*ySlices)
    , slices_decoded(0) {}

  FragmentedPictureData (const PictureFormat& pictureFormat, int waveletDepth,
                         int ySlices, int xSlices,
                         const Array2D &sb,
                         const Array1D &qm,
                         int h, int w, ColourFormat cf)
    : slices(pictureFormat, waveletDepth,
             ySlices, xSlices)
    , qMatrix(qm)
    , picFormat(h, w, cf)
    , slice_prefix(0)
    , slice_size_scalar(0)
    , slice_bytes(sb)
    , slices_needed(xSlices*ySlices)
    , slices_decoded(0) {}

  Slices slices;
  const Array1D qMatrix;
  const PictureFormat picFormat;
  int slice_prefix;
  int slice_size_scalar;
  Array2D slice_bytes;

  int slices_needed;
  int slices_decoded;
};

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

try { //Giant try block around all code to get error messages

  ProgramParams params = getCommandLineParams(argc, argv, details);
  if (!params.error.empty()) {
    cerr << "Command line error: " << params.error << endl;
    return EXIT_FAILURE;
  }

  // Create convenient aliases for program parameters
  const string inFileName = params.inFileName;
  const string outFileName = params.outFileName;
  const bool verbose = params.verbose;
  const Output output = params.output;

  if (verbose) {
    clog << endl;
    for (int arg=0; arg<argc; ++arg) { //Output command line
      if (arg) clog << " ";
      clog << argv[arg];
    }
    clog << endl;
    clog << "input file = " << inFileName << endl;
    clog << "output file = " << outFileName << endl;
  }

  // Open input file or use standard input
  // Input stream is read only binary mode.
  // No point in continuing if can't open input file.
  filebuf inFileBuffer; // For file input. Needs to be defined here to remain in scope
  streambuf *pInBuffer; // Either standard input buffer or a file buffer
  if (inFileName=="-") { // Use standard in
    //Set standard input to binary mode.
    //Only relevant for Windows (*nix is always binary)
    if ( utils::setstdinmode(std::ios_base::binary) == -1 ) {
        cerr << "Error: could not set standard input to binary mode" << endl;
        return EXIT_FAILURE;
    }
    pInBuffer = cin.rdbuf();
  }
  else { // Open file inFileName and use it for input
    pInBuffer = inFileBuffer.open(inFileName.c_str(), ios_base::in|ios_base::binary);
    if (!pInBuffer) {
      perror((string("Failed to open input file \"")+inFileName+"\"").c_str());
      return EXIT_FAILURE;
    }
  }
  istream inStream(pInBuffer);

  // Open output file or use standard output.
  // Output stream is write only binary mode
  // No point in continuing if can't open output file.
  filebuf outFileBuffer; // For file output. Needs to be defined here to remain in scope
  streambuf *pOutBuffer; // Either standard output buffer or a file buffer
  if (outFileName=="-") { // Use standard out
    //Set standard input to binary mode.
    //Only relevant for Windows (*nix is always binary)
    if ( utils::setstdoutmode(std::ios_base::binary) == -1 ) {
        cerr << "Error: could not set standard output to binary mode" << endl;
        return EXIT_FAILURE;
    }
    pOutBuffer = cout.rdbuf();
  }
  else { // Open file outFileName and use it for output
    pOutBuffer = outFileBuffer.open(outFileName.c_str(), ios_base::out|ios_base::binary);
    if (!pOutBuffer) {
      perror((string("Failed to open output file \"")+outFileName+"\"").c_str());
      return EXIT_FAILURE;
    }
  }
  ostream outStream(pOutBuffer);

  int frame = 0;
  int pic = 0;
  inStream >> dataunitio::synchronise;
  // Jump back 4 bytes in the stream so the prefix header can be read and checked at the start of the loop
  inStream.seekg(-4,ios_base::cur);

  /* In reality the decode can't happen without these values being set, but
     the compiler doesn't like leaving them uninitialised. */
  bool have_seq_hdr         = false;
  int height                = 0;
  int width                 = 0;
  ColourFormat chromaFormat = CF_UNSET;
  int bytes                 = 0;
  int lumaDepth             = 0;
  int chromaDepth           = 0;
  bool interlaced           = false;
  bool topFieldFirst        = false;
  WaveletKernel kernel      = NullKernel;
  int waveletDepth          = -1;
  int ySlices;
  int xSlices;
  int compressedBytes;
  int sliceScalar;
  int slicePrefix;
  boost::scoped_ptr<Frame> outFrame;

  std::map<int, FragmentedPictureData *> fragmentReassemblingSlices;

  while (true) {
    // Read data unit from stream
    inStream.peek();
    if (inStream.eof()) {
      clog << "End of data stream reached successfully, exiting." << endl;
      return EXIT_SUCCESS;
    }
    else if(inStream.fail()){
      clog << "An error has occured in the data stream, exiting." << endl;
      return EXIT_FAILURE;
    }

    DataUnit du;
    inStream >> du;

    if (verbose) {
      clog << endl;
      clog << "Have read data unit of type: " << du.type << endl;
    }

    switch (du.type) {
    case SEQUENCE_HEADER:
      {
        if (verbose) clog << "Parsing Sequence Header" << endl << endl;
        SequenceHeader seq_hdr;
        inStream >> seq_hdr;

        if (verbose) {
          clog << "height        = " << seq_hdr.height << endl;
          clog << "width         = " << seq_hdr.width << endl;
          clog << "chroma format = " << seq_hdr.chromaFormat << endl;
          clog << "interlaced    = " << std::boolalpha << seq_hdr.interlace << endl;
          if(seq_hdr.frameRate!=0){
            clog << "frame rate    = " << seq_hdr.frameRate << endl;
          } else {
            clog << "custom frame rate: "
                 << seq_hdr.frameRateNumer << "/"
                 << seq_hdr.frameRateDenom << endl;
          }
          if(seq_hdr.pixelAspectRatio!=AR0){
            clog << "pixel aspect ratio index = " << (int)seq_hdr.pixelAspectRatio << endl;
          } else {
            clog << "custom pixel aspect ratio: "
                 << seq_hdr.pixelAspectRatioNumer << "/"
                 << seq_hdr.pixelAspectRatioDenom << endl;
          }
          if(seq_hdr.bitdepth!=0){
            clog << "bitdepth index = " << seq_hdr.bitdepth << endl;
          } else {
            clog << "custom bitdepth info: " << endl;
            clog <<"\tluma (excursion, offset): "<< seq_hdr.lumaExcursion<<", "<<seq_hdr.lumaOffset<<endl;
            clog <<"\tcolor difference (excursion, offset): "<< seq_hdr.colorDiffExcursion<<", "<<seq_hdr.colorDiffOffset<<endl;
          }
        }

        height        = seq_hdr.height;
        width         = seq_hdr.width;
        chromaFormat  = seq_hdr.chromaFormat;
        interlaced    = seq_hdr.interlace;
        topFieldFirst = seq_hdr.topFieldFirst;
        lumaDepth     = seq_hdr.bitdepth;
        chromaDepth   = seq_hdr.bitdepth;

        if (seq_hdr.bitdepth == 8)
          bytes = 1;
        else
          bytes = 2;

        have_seq_hdr = true;
      }
      break;
    case END_OF_SEQUENCE:
      if (verbose) {
        clog << "End of Sequence after " << frame << " frames" << endl;
      }
      break;
    case AUXILIARY_DATA:
      if (du.length()<0) throw std::logic_error("Auxilliary data length is less than zero.");
      inStream.seekg(du.length(),ios_base::cur);
      break;
    case PADDING_DATA:
      if (du.length()<0) throw std::logic_error("Padding data length is less than zero.");
      inStream.seekg(du.length(),ios_base::cur);
      break;
    case LD_PICTURE:
      {
        if (verbose) clog << "Parsing Picture Header" << endl;

        PictureHeader pichdr;
        PicturePreamble preamble;
        inStream >> dataunitio::lowDelay
                 >> pichdr
                 >> preamble;

        if (verbose) {
          clog << "Picture number      : " << pichdr.picture_number << endl;
          clog << "Wavelet Kernel      : " << preamble.wavelet_kernel << endl;
          clog << "Transform Depth     : " << preamble.depth << endl;
          clog << "Slices Horizontally : " << preamble.slices_x << endl;
          clog << "Slices Verically    : " << preamble.slices_y << endl;
          clog << "Slice Bytes         : " << preamble.slice_bytes << endl;
        }

        ySlices = preamble.slices_y;
        xSlices = preamble.slices_x;
        waveletDepth = preamble.depth;
        kernel = preamble.wavelet_kernel;
        compressedBytes = (preamble.slice_bytes.numerator*preamble.slices_y*preamble.slices_x)/preamble.slice_bytes.denominator;
      }

      if (!have_seq_hdr) {
        clog << "Cannot decode frame, no previous sequence header!" << endl;
      } else {
        // Calculate number of slices per picture
        const int pictureHeight = ( (interlaced) ? height/2 : height);
        const int paddedPictureHeight = paddedSize(pictureHeight, waveletDepth);
        const int paddedWidth = paddedSize(width, waveletDepth);

        // Calculate the quantisation matrix
        const Array1D qMatrix = quantMatrix(kernel, waveletDepth);
        if (verbose) {
          clog << "Quantisation matrix = " << qMatrix[0];
          for (unsigned int i=1; i<qMatrix.size(); ++i) {
            clog << ", " << qMatrix[i];
          }
          clog << endl;
        }

        // First calculate number of bytes for each slice
        const int pictureBytes = (interlaced ? compressedBytes/2 : compressedBytes);
        const Array2D sliceBytes = slice_bytes(ySlices, xSlices, pictureBytes, 1);
        const PictureFormat transformFormat(paddedPictureHeight, paddedWidth, chromaFormat);
        Slices inSlices(transformFormat, waveletDepth, ySlices, xSlices);

        // Define picture format (field or frame)
        const PictureFormat picFormat(pictureHeight, width, chromaFormat);

        // Read input from planar file
        if (verbose) {
          if (interlaced)
            clog << "Reading compressed input field " << pic << " of frame " << frame;
          else
            clog << "Reading compressed input frame number " << frame;
        }
        clog.flush(); // Make sure comments written to log file.
        inStream >> sliceio::lowDelay(sliceBytes); // Read input in Low Delay mode
        inStream >> inSlices; // Read the compressed input picture
        // Check picture was read OK
        if (!inStream) {
          cerr << "\rFailed to read LD compressed frame" << endl;
          continue;
        }
        else if (verbose) clog << endl;

        // Reorder quantised coefficients from slice order to transform order
        if (verbose) clog << "Merge slices into full picture" << endl;
        const Picture yuvQCoeffs = merge_blocks(inSlices.yuvSlices);

        if (output==INDICES) {
          //Write quantisation indices as 1 byte unsigned values
          clog << "Writing quantisation indices to output file" << endl;
          outStream << arrayio::wordWidth(1); //1 byte per sample
          outStream << arrayio::unsigned_binary; // unsigned output
          outStream << inSlices.qIndices;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        if (output==QUANTISED) {
          //Write quantised transform output as 4 byte 2's comp values
          clog << "Writing quantised transform coefficients to output file" << endl;
          outStream << pictureio::wordWidth(4); // 4 bytes per sample
          outStream << pictureio::signed_binary; // 2's comp output
          outStream << yuvQCoeffs;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        // Inverse quantise in transform order
        if (verbose) clog << "Inverse quantise" << endl;
        const Picture yuvTransform = inverse_quantise_transform(yuvQCoeffs, inSlices.qIndices, qMatrix);

        if (output==TRANSFORM) {
          //Write transform output as 4 byte 2's comp values
          clog << "Writing transform coefficients to output file" << endl;
          outStream << pictureio::wordWidth(4); //4 bytes per sample
          outStream << pictureio::signed_binary;
          outStream << yuvTransform;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        // Inverse wavelet transform
        if (verbose) clog << "Inverse transform" << endl;
        const Picture outPicture = inverseWaveletTransform(yuvTransform, kernel, waveletDepth, picFormat);

        // Copy picture to output frame
        if (verbose) clog << "Copy picture to output frame" << endl;
        if (interlaced) {
          if (pic == 0) {
            const PictureFormat frameFormat(height, width, chromaFormat);
            outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
            outFrame->firstField(outPicture);

            pic++;
            continue;
          }

          outFrame->secondField(outPicture);
          pic = 0;
        }
        else { //progressive
          const PictureFormat frameFormat(height, width, chromaFormat);
          outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
          outFrame->frame(outPicture);
        }

        if (verbose) clog << "Clipping output" << endl;
        {
          const int yMin = -utils::pow(2, lumaDepth-1);
          const int yMax = utils::pow(2, lumaDepth-1)-1;
          const int uvMin = -utils::pow(2, chromaDepth-1);
          const int uvMax = utils::pow(2, chromaDepth-1)-1;
          outFrame->frame(clip(*outFrame, yMin, yMax, uvMin, uvMax));
        }

        if (verbose) clog << "Writing decoded output file" << endl;
        outStream << pictureio::wordWidth(bytes); // Set number of bytes per value in file
        outStream << pictureio::left_justified;
        outStream << pictureio::offset_binary;
        outStream << pictureio::bitDepth(lumaDepth, chromaDepth); // Set luma and chroma bit depths
        outStream << *outFrame;
        if (!outStream) {
          cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
          return EXIT_FAILURE;
        }

        ++frame;
      }
      break;
    case HQ_PICTURE:
      {
        if (verbose) clog << "Parsing Picture Header" << endl;

        PictureHeader pichdr;
        PicturePreamble preamble;
        inStream >> dataunitio::highQualityVBR(0, 1)
                 >> pichdr
                 >> preamble;
        if (verbose) {
          clog << "Picture number      : " << pichdr.picture_number << endl;
          clog << "Wavelet Kernel      : " << preamble.wavelet_kernel << endl;
          clog << "Transform Depth     : " << preamble.depth << endl;
          clog << "Slices Horizontally : " << preamble.slices_x << endl;
          clog << "Slices Verically    : " << preamble.slices_y << endl;
          clog << "Slice Prefix        : " << preamble.slice_prefix << endl;
          clog << "Slice Size Scalar   : " << preamble.slice_size_scalar << endl;
        }

        ySlices = preamble.slices_y;
        xSlices = preamble.slices_x;
        waveletDepth = preamble.depth;
        kernel = preamble.wavelet_kernel;
        sliceScalar = preamble.slice_size_scalar;
        slicePrefix = preamble.slice_prefix;
      }

      if (!have_seq_hdr) {
        clog << "Cannot decode frame, no previous sequence header!" << endl;
      } else {
        // Calculate number of slices per picture
        const int pictureHeight = ( (interlaced) ? height/2 : height);
        const int paddedPictureHeight = paddedSize(pictureHeight, waveletDepth);
        const int paddedWidth = paddedSize(width, waveletDepth);

        // Calculate the quantisation matrix
        const Array1D qMatrix = quantMatrix(kernel, waveletDepth);
        if (verbose) {
          clog << "Quantisation matrix = " << qMatrix[0];
          for (unsigned int i=1; i<qMatrix.size(); ++i) {
            clog << ", " << qMatrix[i];
          }
          clog << endl;
        }

        // Construct an container to read the compressed data into.
        const PictureFormat transformFormat(paddedPictureHeight, paddedWidth, chromaFormat);
        Slices inSlices(transformFormat, waveletDepth, ySlices, xSlices);

        // Define picture format (field or frame)
        const PictureFormat picFormat(pictureHeight, width, chromaFormat);

        // Read input from planar file
        if (verbose) {
          if (interlaced)
            clog << "Reading compressed input field " << pic << " of frame " << frame;
          else
            clog << "Reading compressed input frame number " << frame;
        }
        clog.flush(); // Make sure comments written to log file.
        inStream >> sliceio::highQualityVBR(slicePrefix, sliceScalar); // Read input in HQ VBR mode
        inStream >> inSlices; // Read the compressed input picture
        // Check picture was read OK
        if (!inStream) {
          cerr << "\rFailed to read HQ compressed frame" << endl;
          continue;
        }
        else if (verbose) clog << endl;

        // Reorder quantised coefficients from slice order to transform order
        if (verbose) clog << "Merge slices into full picture" << endl;
        const Picture yuvQCoeffs = merge_blocks(inSlices.yuvSlices);

        if (output==INDICES) {
          //Write quantisation indices as 1 byte unsigned values
          clog << "Writing quantisation indices to output file" << endl;
          outStream << arrayio::wordWidth(1); //1 byte per sample
          outStream << arrayio::unsigned_binary; // unsigned output
          outStream << inSlices.qIndices;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        if (output==QUANTISED) {
          //Write quantised transform output as 4 byte 2's comp values
          clog << "Writing quantised transform coefficients to output file" << endl;
          outStream << pictureio::wordWidth(4); // 4 bytes per sample
          outStream << pictureio::signed_binary; // 2's comp output
          outStream << yuvQCoeffs;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        // Inverse quantise in transform order
        if (verbose) clog << "Inverse quantise" << endl;
        const Picture yuvTransform = inverse_quantise_transform_np(yuvQCoeffs, inSlices.qIndices, qMatrix);

        if (output==TRANSFORM) {
          //Write transform output as 4 byte 2's comp values
          clog << "Writing transform coefficients to output file" << endl;
          outStream << pictureio::wordWidth(4); //4 bytes per sample
          outStream << pictureio::signed_binary;
          outStream << yuvTransform;
          if (!outStream) {
            cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
            return EXIT_FAILURE; }
          continue; // omit rest of processing for this picture
        }

        // Inverse wavelet transform
        if (verbose) clog << "Inverse transform" << endl;
        const Picture outPicture = inverseWaveletTransform(yuvTransform, kernel, waveletDepth, picFormat);

        // Copy picture to output frame
        if (verbose) clog << "Copy picture to output frame" << endl;
        if (interlaced) {
          if (pic == 0) {
            const PictureFormat frameFormat(height, width, chromaFormat);
            outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));

            outFrame->firstField(outPicture);
            pic++;
            continue;
          }

          outFrame->secondField(outPicture);

          pic = 0;
        }
        else { //progressive
          const PictureFormat frameFormat(height, width, chromaFormat);
          outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
          outFrame->frame(outPicture);
        }

        if (verbose) clog << "Clipping output" << endl;
        {
          const int yMin = -utils::pow(2, lumaDepth-1);
          const int yMax = utils::pow(2, lumaDepth-1)-1;
          const int uvMin = -utils::pow(2, chromaDepth-1);
          const int uvMax = utils::pow(2, chromaDepth-1)-1;
          outFrame->frame(clip(*outFrame, yMin, yMax, uvMin, uvMax));
        }

        if (verbose) clog << "Writing decoded output file" << endl;
        outStream << pictureio::wordWidth(bytes); // Set number of bytes per value in file
        outStream << pictureio::left_justified;
        outStream << pictureio::offset_binary;
        outStream << pictureio::bitDepth(lumaDepth, chromaDepth); // Set luma and chroma bit depths
        outStream << *outFrame;
        if (!outStream) {
          cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
          return EXIT_FAILURE;
        }

        ++frame;
      }
      break;
    case LD_FRAGMENT:
      {
        if (verbose) clog << "Parsing LD Fragment" << endl;

        PictureHeader pichdr;
        Fragment frag;
        inStream >> dataunitio::lowDelay
                 >> pichdr
                 >> frag;

        if (frag.n_slices() == 0) {
          if (verbose) clog << "Parsing Picture Header" << endl;
          PicturePreamble preamble;
          inStream >> preamble;
          if (verbose) {
            clog << "Picture number      : " << pichdr.picture_number << endl;
            clog << "Wavelet Kernel      : " << preamble.wavelet_kernel << endl;
            clog << "Transform Depth     : " << preamble.depth << endl;
            clog << "Slices Horizontally : " << preamble.slices_x << endl;
            clog << "Slices Verically    : " << preamble.slices_y << endl;
            clog << "Slice Bytes         : " << preamble.slice_bytes << endl;
          }

          ySlices = preamble.slices_y;
          xSlices = preamble.slices_x;
          waveletDepth = preamble.depth;
          kernel = preamble.wavelet_kernel;
          compressedBytes = (preamble.slice_bytes.numerator*preamble.slices_y*preamble.slices_x)/preamble.slice_bytes.denominator;

          if (!have_seq_hdr) {
            clog << "Cannot decode frame, no previous sequence header!" << endl;
          } else {
            // Calculate number of slices per picture
            const int pictureHeight = ( (interlaced) ? height/2 : height);
            const int paddedPictureHeight = paddedSize(pictureHeight, waveletDepth);
            const int paddedWidth = paddedSize(width, waveletDepth);

            // Calculate the quantisation matrix
            const Array1D qMatrix = quantMatrix(kernel, waveletDepth);
            if (verbose) {
              clog << "Quantisation matrix = " << qMatrix[0];
              for (unsigned int i=1; i<qMatrix.size(); ++i) {
                clog << ", " << qMatrix[i];
              }
              clog << endl;
            }

            // First calculate number of bytes for each slice
            const int pictureBytes = (interlaced ? compressedBytes/2 : compressedBytes);
            const Array2D sliceBytes = slice_bytes(ySlices, xSlices, pictureBytes, 1);
            const PictureFormat transformFormat(paddedPictureHeight, paddedWidth, chromaFormat);

            // Define picture format (field or frame)
            const PictureFormat picFormat(pictureHeight, width, chromaFormat);

            fragmentReassemblingSlices[pichdr.picture_number] = new FragmentedPictureData(transformFormat,
                                                                                waveletDepth,
                                                                                ySlices,
                                                                                xSlices,
                                                                                sliceBytes,
                                                                                qMatrix,
                                                                                pictureHeight, width, chromaFormat);
          }
        } else {
          if (fragmentReassemblingSlices.count(pichdr.picture_number) == 0) {
            clog << "Cannot decode slices as no picture header yet read for picture number " << pichdr.picture_number << endl;
          } else {
            if (verbose) {
              clog << "Picture " << pichdr.picture_number << ": Reading " << frag.n_slices()
                   << " slices, starting from (" << frag.slice_offset_x() << ", " << frag.slice_offset_y() << ")" << endl;
            }
            inStream >> sliceio::lowDelay(fragmentReassemblingSlices[pichdr.picture_number]->slice_bytes);
            inStream >> sliceio::ExpectedSlicesForFragment(frag);
            inStream >> fragmentReassemblingSlices[pichdr.picture_number]->slices;
            fragmentReassemblingSlices[pichdr.picture_number]->slices_decoded += frag.n_slices();

            if (fragmentReassemblingSlices[pichdr.picture_number]->slices_decoded >= fragmentReassemblingSlices[pichdr.picture_number]->slices_needed) {
              Slices &inSlices = fragmentReassemblingSlices[pichdr.picture_number]->slices;
              const Array1D &qMatrix = fragmentReassemblingSlices[pichdr.picture_number]->qMatrix;
              const PictureFormat &picFormat = fragmentReassemblingSlices[pichdr.picture_number]->picFormat;
              // Reorder quantised coefficients from slice order to transform order
              if (verbose) clog << "Merge slices into full picture" << endl;
              const Picture yuvQCoeffs = merge_blocks(inSlices.yuvSlices);

              if (output==INDICES) {
                //Write quantisation indices as 1 byte unsigned values
                clog << "Writing quantisation indices to output file" << endl;
                outStream << arrayio::wordWidth(1); //1 byte per sample
                outStream << arrayio::unsigned_binary; // unsigned output
                outStream << inSlices.qIndices;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              if (output==QUANTISED) {
                //Write quantised transform output as 4 byte 2's comp values
                clog << "Writing quantised transform coefficients to output file" << endl;
                outStream << pictureio::wordWidth(4); // 4 bytes per sample
                outStream << pictureio::signed_binary; // 2's comp output
                outStream << yuvQCoeffs;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              // Inverse quantise in transform order
              if (verbose) clog << "Inverse quantise" << endl;
              const Picture yuvTransform = inverse_quantise_transform(yuvQCoeffs, inSlices.qIndices, qMatrix);

              if (output==TRANSFORM) {
                //Write transform output as 4 byte 2's comp values
                clog << "Writing transform coefficients to output file" << endl;
                outStream << pictureio::wordWidth(4); //4 bytes per sample
                outStream << pictureio::signed_binary;
                outStream << yuvTransform;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              // Inverse wavelet transform
              if (verbose) clog << "Inverse transform" << endl;
              const Picture outPicture = inverseWaveletTransform(yuvTransform, kernel, waveletDepth, picFormat);

              // Copy picture to output frame
              if (verbose) clog << "Copy picture to output frame" << endl;
              if (interlaced) {
                if (pic == 0) {
                  const PictureFormat frameFormat(height, width, chromaFormat);
                  outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
                  outFrame->firstField(outPicture);

                  pic++;
                  delete fragmentReassemblingSlices[pichdr.picture_number];
                  fragmentReassemblingSlices.erase(pichdr.picture_number);
                  continue;
                }

                outFrame->secondField(outPicture);
                pic = 0;
              }
              else { //progressive
                const PictureFormat frameFormat(height, width, chromaFormat);
                outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
                outFrame->frame(outPicture);
              }

              if (verbose) clog << "Clipping output" << endl;
              {
                const int yMin = -utils::pow(2, lumaDepth-1);
                const int yMax = utils::pow(2, lumaDepth-1)-1;
                const int uvMin = -utils::pow(2, chromaDepth-1);
                const int uvMax = utils::pow(2, chromaDepth-1)-1;
                outFrame->frame(clip(*outFrame, yMin, yMax, uvMin, uvMax));
              }

              if (verbose) clog << "Writing decoded output file" << endl;
              outStream << pictureio::wordWidth(bytes); // Set number of bytes per value in file
              outStream << pictureio::left_justified;
              outStream << pictureio::offset_binary;
              outStream << pictureio::bitDepth(lumaDepth, chromaDepth); // Set luma and chroma bit depths
              outStream << *outFrame;
              if (!outStream) {
                cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                return EXIT_FAILURE;
              }

              ++frame;
              delete fragmentReassemblingSlices[pichdr.picture_number];
              fragmentReassemblingSlices.erase(pichdr.picture_number);
            }
          }
        }
      }
      break;
    case HQ_FRAGMENT:
      {
        if (verbose) clog << "Parsing HQ Fragment" << endl;

        PictureHeader pichdr;
        Fragment frag;
        inStream >> dataunitio::highQualityVBR(0, 1)
                 >> pichdr
                 >> frag;

        if (frag.n_slices() == 0) {
          if (verbose) clog << "Parsing Picture Header" << endl;
          PicturePreamble preamble;
          inStream >> preamble;
          if (verbose) {
            clog << "Picture number      : " << (int)pichdr.picture_number << endl;
            clog << "Wavelet Kernel      : " << preamble.wavelet_kernel << endl;
            clog << "Transform Depth     : " << preamble.depth << endl;
            clog << "Slices Horizontally : " << preamble.slices_x << endl;
            clog << "Slices Verically    : " << preamble.slices_y << endl;
            clog << "Slice Prefix        : " << preamble.slice_prefix << endl;
            clog << "Slice Size Scalar   : " << preamble.slice_size_scalar << endl;
          }

          ySlices = preamble.slices_y;
          xSlices = preamble.slices_x;
          waveletDepth = preamble.depth;
          kernel = preamble.wavelet_kernel;
          sliceScalar = preamble.slice_size_scalar;
          slicePrefix = preamble.slice_prefix;

          if (!have_seq_hdr) {
            clog << "Cannot decode frame, no previous sequence header!" << endl;
          } else {
            // Calculate number of slices per picture
            const int pictureHeight = ( (interlaced) ? height/2 : height);
            const int paddedPictureHeight = paddedSize(pictureHeight, waveletDepth);
            const int paddedWidth = paddedSize(width, waveletDepth);

            // Calculate the quantisation matrix
            const Array1D qMatrix = quantMatrix(kernel, waveletDepth);
            if (verbose) {
              clog << "Quantisation matrix = " << qMatrix[0];
              for (unsigned int i=1; i<qMatrix.size(); ++i) {
                clog << ", " << qMatrix[i];
              }
              clog << endl;
            }

            // Construct an container to read the compressed data into.
            const PictureFormat transformFormat(paddedPictureHeight, paddedWidth, chromaFormat);
            fragmentReassemblingSlices[pichdr.picture_number] = new FragmentedPictureData(transformFormat, waveletDepth, ySlices, xSlices,
                                                                                slicePrefix, sliceScalar,
                                                                                qMatrix,
                                                                                pictureHeight, width, chromaFormat);

          }
        } else {
          if (fragmentReassemblingSlices.count(pichdr.picture_number) == 0) {
            clog << "Cannot decode slices as no picture header yet read for picture number " << pichdr.picture_number << endl;
          } else {
            if (verbose) {
              clog << "Picture " << pichdr.picture_number << ": Reading " << frag.n_slices()
                   << " slices, starting from (" << frag.slice_offset_x() << ", " << frag.slice_offset_y() << ")" << endl;
            }
            inStream >> sliceio::highQualityVBR(fragmentReassemblingSlices[pichdr.picture_number]->slice_prefix,
                                                fragmentReassemblingSlices[pichdr.picture_number]->slice_size_scalar);
            inStream >> sliceio::ExpectedSlicesForFragment(frag);
            inStream >> fragmentReassemblingSlices[pichdr.picture_number]->slices;
            fragmentReassemblingSlices[pichdr.picture_number]->slices_decoded += frag.n_slices();

            if (fragmentReassemblingSlices[pichdr.picture_number]->slices_decoded >= fragmentReassemblingSlices[pichdr.picture_number]->slices_needed) {
              Slices &inSlices = fragmentReassemblingSlices[pichdr.picture_number]->slices;
              // Reorder quantised coefficients from slice order to transform order
              if (verbose) clog << "Merge slices into full picture" << endl;
              const Picture yuvQCoeffs = merge_blocks(inSlices.yuvSlices);

              if (output==INDICES) {
                //Write quantisation indices as 1 byte unsigned values
                clog << "Writing quantisation indices to output file" << endl;
                outStream << arrayio::wordWidth(1); //1 byte per sample
                outStream << arrayio::unsigned_binary; // unsigned output
                outStream << inSlices.qIndices;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              if (output==QUANTISED) {
                //Write quantised transform output as 4 byte 2's comp values
                clog << "Writing quantised transform coefficients to output file" << endl;
                outStream << pictureio::wordWidth(4); // 4 bytes per sample
                outStream << pictureio::signed_binary; // 2's comp output
                outStream << yuvQCoeffs;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              // Inverse quantise in transform order
              if (verbose) clog << "Inverse quantise" << endl;
              const Picture yuvTransform = inverse_quantise_transform_np(yuvQCoeffs, inSlices.qIndices, fragmentReassemblingSlices[pichdr.picture_number]->qMatrix);

              if (output==TRANSFORM) {
                //Write transform output as 4 byte 2's comp values
                clog << "Writing transform coefficients to output file" << endl;
                outStream << pictureio::wordWidth(4); //4 bytes per sample
                outStream << pictureio::signed_binary;
                outStream << yuvTransform;
                if (!outStream) {
                  cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                  return EXIT_FAILURE; }
                delete fragmentReassemblingSlices[pichdr.picture_number];
                fragmentReassemblingSlices.erase(pichdr.picture_number);
                continue; // omit rest of processing for this picture
              }

              // Inverse wavelet transform
              if (verbose) clog << "Inverse transform" << endl;
              const Picture outPicture = inverseWaveletTransform(yuvTransform, kernel, waveletDepth, fragmentReassemblingSlices[pichdr.picture_number]->picFormat);

              // Copy picture to output frame
              if (verbose) clog << "Copy picture to output frame" << endl;
              if (interlaced) {
                if (pic == 0) {
                  const PictureFormat frameFormat(height, width, chromaFormat);
                  outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));

                  outFrame->firstField(outPicture);
                  pic++;
                  delete fragmentReassemblingSlices[pichdr.picture_number];
                  fragmentReassemblingSlices.erase(pichdr.picture_number);
                  continue;
                }

                outFrame->secondField(outPicture);

                pic = 0;
              }
              else { //progressive
                const PictureFormat frameFormat(height, width, chromaFormat);
                outFrame.reset(new Frame(frameFormat, interlaced, topFieldFirst));
                outFrame->frame(outPicture);
              }

              if (verbose) clog << "Clipping output" << endl;
              {
                const int yMin = -utils::pow(2, lumaDepth-1);
                const int yMax = utils::pow(2, lumaDepth-1)-1;
                const int uvMin = -utils::pow(2, chromaDepth-1);
                const int uvMax = utils::pow(2, chromaDepth-1)-1;
                outFrame->frame(clip(*outFrame, yMin, yMax, uvMin, uvMax));
              }

              if (verbose) clog << "Writing decoded output file" << endl;
              outStream << pictureio::wordWidth(bytes); // Set number of bytes per value in file
              outStream << pictureio::left_justified;
              outStream << pictureio::offset_binary;
              outStream << pictureio::bitDepth(lumaDepth, chromaDepth); // Set luma and chroma bit depths
              outStream << *outFrame;
              if (!outStream) {
                cerr << "Failed to write output file \"" << outFileName << "\"" << endl;
                return EXIT_FAILURE;
              }

              ++frame;
              delete fragmentReassemblingSlices[pichdr.picture_number];
              fragmentReassemblingSlices.erase(pichdr.picture_number);
            }
          }
        }
      }
      break;
    default:
      continue;
    }
  } //End frame loop

} // end of try block

// Report error messages from try block
catch (const std::exception& ex) {
    cout << "Error: " << ex.what() << endl;
    return EXIT_FAILURE;
}
  // Program should never reach here!
  return EXIT_FAILURE;
}

ext: cpp


text:
#include "toy/file/io/DefaultZip.hpp"
#include <boost/filesystem.hpp>
#include <iostream>

using namespace toy;
using namespace file;
using namespace io;

bool DefaultZip::isEnd()
{
	return false;
}

bool DefaultZip::isEmpty()
{
	return true;
}

void DefaultZip::close()
{
	;
}

bool DefaultZip::openDir(std::string )
{
	return true;
}

void DefaultZip::closeDir()
{
	// TBD
}

bool DefaultZip::open(std::string )
{
	return true;
}

uint32_t DefaultZip::read(void *,uint32_t )
{
	return true;
}

bool DefaultZip::write(const void *,uint32_t )
{
	if ( isEmpty() ) return 0;
	return true;
}

bool DefaultZip::seek(int ,int32_t )
{
	if ( isEmpty() ) return 0;

	return true;
}

std::string DefaultZip::getFileName()
{
	return std::string();
}

std::string DefaultZip::getDirName()
{
	return std::string();
}

max_stars_repo_name: ToyAuthor/ToyBox

max_issues_repo_name: ToyAuthor/ToyBox

max_forks_repo_name: ToyAuthor/ToyBox


text:
// This file has been generated by Py++.

// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
// at http://www.boost.org/LICENSE_1_0.txt)
//
// Header file multimap.hpp
//
// Indexing algorithms support for std::multimap instances
//
// History
// =======
// 2006/10/27   Roman     File creation from map.hpp
// 2008/12/08   Roman   Change indexing suite layout
// 2010/04/29   Roman   Adding "__len__" method
//

#ifndef BOOST_PYTHON_INDEXING_MULTIMAP_HPP
#define BOOST_PYTHON_INDEXING_MULTIMAP_HPP

#include <indexing_suite/container_traits.hpp>
#include <indexing_suite/container_suite.hpp>
#include <indexing_suite/algorithms.hpp>
#include <boost/detail/workaround.hpp>
#include <functional>
#include <map>
#include <indexing_suite/pair.hpp>

namespace boost { namespace python { namespace indexing {
  /////////////////////////////////////////////////////////////////////////
  // ContainerTraits implementation for std::map instances
  /////////////////////////////////////////////////////////////////////////

  template<typename Container>
  class multimap_traits : public base_container_traits<Container>
  {
    typedef base_container_traits<Container> base_class;

  public:
# if BOOST_WORKAROUND (BOOST_MSVC, <= 1200)
    // MSVC6 has a nonstandard name for mapped_type in std::multimap
    typedef typename Container::referent_type value_type;
# else
    typedef typename Container::mapped_type value_type;
# endif
    typedef value_type &                    reference;
    typedef typename Container::key_type    index_type; // operator[]
    typedef typename Container::key_type    key_type;   // find, count, ...

    typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
      value_param;
    typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
      key_param;
    typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <index_type>::param_type
      index_param;

    BOOST_STATIC_CONSTANT(
        method_set_type,
        supported_methods = (
              method_iter

            | method_getitem
            | method_contains
            | method_count
            | method_has_key
            | method_len

            | detail::method_set_if<
                  base_class::is_mutable,
                    method_setitem
                  | method_delitem
                  | method_insert
              >::value
        ));
  };

  /////////////////////////////////////////////////////////////////////////
  // Algorithms implementation for std::multimap instances
  /////////////////////////////////////////////////////////////////////////

  template<typename ContainerTraits, typename Ovr = detail::no_override>
  class multimap_algorithms
    : public assoc_algorithms
        <ContainerTraits,
        typename detail::maybe_override
            <multimap_algorithms<ContainerTraits, Ovr>, Ovr>
          ::type>
  {
    typedef multimap_algorithms<ContainerTraits, Ovr> self_type;
    typedef typename detail::maybe_override<self_type, Ovr>::type most_derived;
    typedef assoc_algorithms<ContainerTraits, most_derived> Parent;

  public:
    typedef typename Parent::container container;
    typedef typename Parent::reference reference;
    typedef typename Parent::index_param index_param;
    typedef typename Parent::value_param value_param;

    static boost::python::list get (container &, index_param);
    // Version to return only the mapped type

    static boost::python::list keys( container & );

    static void      assign     (container &, index_param, value_param);
    static void      insert     (container &, index_param, value_param);

    template<typename PythonClass, typename Policy>
    static void visit_container_class( PythonClass &pyClass, Policy const &policy)
    {
      ContainerTraits::visit_container_class (pyClass, policy);
      pyClass.def( "keys", &self_type::keys );

      typedef BOOST_DEDUCED_TYPENAME most_derived::container::value_type value_type;
      mapping::register_value_type< PythonClass, value_type, Policy >( pyClass );
      //now we can expose iterators functionality
      pyClass.def( "__iter__", python::iterator< BOOST_DEDUCED_TYPENAME most_derived::container >() );

    }

  };

  template<
    class Container,
    method_set_type MethodMask = all_methods,
    class Traits = multimap_traits<Container>
  >
  struct multimap_suite
    : container_suite<Container, MethodMask, multimap_algorithms<Traits> >
  {
  };

  /////////////////////////////////////////////////////////////////////////
  // Index into a container (multimap version)
  /////////////////////////////////////////////////////////////////////////

  template<typename ContainerTraits, typename Ovr>
  boost::python::list
  multimap_algorithms<ContainerTraits, Ovr>::get (container &c, index_param ix)
  {
    boost::python::list l;
    typedef BOOST_DEDUCED_TYPENAME container::iterator iter_type;
    for( iter_type index = c.lower_bound( ix ); index != c.upper_bound( ix ); ++index ){
        boost::python::object v( index->second );
        l.append( v );
    }
    return l;
  }

  template<typename ContainerTraits, typename Ovr>
  boost::python::list
  multimap_algorithms<ContainerTraits, Ovr>::keys( container &c )
  {
    boost::python::list _keys;
    //For some reason code with set could not be compiled
    //std::set< key_param > unique_keys;
    typedef BOOST_DEDUCED_TYPENAME container::iterator iter_type;
    for( iter_type index = most_derived::begin(c); index != most_derived::end(c); ++index ){
        //if( unique_keys.end() == unique_keys.find( index->first ) ){
        //    unique_keys.insert( index->first );
        if( !_keys.count( index->first ) ){
            _keys.append( index->first );
        }
        //}
    }

    return _keys;
  }

  /////////////////////////////////////////////////////////////////////////
  // Assign a value at a particular index (map version)
  /////////////////////////////////////////////////////////////////////////

  template<typename ContainerTraits, typename Ovr>
  void
  multimap_algorithms<ContainerTraits, Ovr>::assign(
      container &c, index_param ix, value_param val)
  {
    typedef std::pair<
        BOOST_DEDUCED_TYPENAME self_type::container_traits::index_type
        , BOOST_DEDUCED_TYPENAME self_type::container_traits::value_type>
    pair_type;

    // Can't use std::make_pair, because param types may be references
    c.insert (pair_type (ix, val));
  }

  /////////////////////////////////////////////////////////////////////////
  // Insert a new key, value pair into a map
  /////////////////////////////////////////////////////////////////////////

  template<typename ContainerTraits, typename Ovr>
  void
  multimap_algorithms<ContainerTraits, Ovr>::insert(
      container &c, index_param ix, value_param val)
  {
    typedef std::pair
      <BOOST_DEDUCED_TYPENAME self_type::container_traits::index_type,
      BOOST_DEDUCED_TYPENAME self_type::container_traits::value_type>
      pair_type;

    // Can't use std::make_pair, because param types may be references
    c.insert (pair_type (ix, val) );
  }
} } }

#endif // BOOST_PYTHON_INDEXING_MULTIMAP_HPP


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#include "precompiled_sd.hxx"

#include "view/SlsInsertAnimator.hxx"
#include "controller/SlideSorterController.hxx"
#include "controller/SlsAnimationFunction.hxx"
#include "view/SlideSorterView.hxx"
#include "view/SlsLayouter.hxx"
#include "model/SlideSorterModel.hxx"
#include "model/SlsPageEnumerationProvider.hxx"

#include <set>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>

namespace sd { namespace slidesorter { namespace view {

namespace {

class PageObjectRun;

class AnimatorAccess
{
public:
	virtual void AddRun (const ::boost::shared_ptr<PageObjectRun> pRun) = 0;
	virtual void RemoveRun (const ::boost::shared_ptr<PageObjectRun> pRun) = 0;
	virtual model::SlideSorterModel& GetModel (void) const = 0;
	virtual view::SlideSorterView& GetView (void) const = 0;
	virtual ::boost::shared_ptr<controller::Animator> GetAnimator (void) = 0;
	virtual SharedSdWindow GetContentWindow (void) = 0;
};

/** Controller of the position offsets of all page objects in one row or one
	column.
*/
class PageObjectRun : public ::boost::enable_shared_from_this<PageObjectRun>
{
public:
	PageObjectRun (
		AnimatorAccess& rAnimatorAccess,
		const sal_Int32 nRunIndex,
		const sal_Int32 nStartIndex,
		const sal_Int32 nEndIndex);
	~PageObjectRun (void);

	void operator () (const double nTime);

	void UpdateOffsets(
		const InsertPosition& rInsertPosition,
		const view::Layouter& GetLayouter);
	void ResetOffsets (const controller::Animator::AnimationMode eMode);

	/// Index of the row or column that this run represents.
	sal_Int32 mnRunIndex;
	/// The index at which to make place for the insertion indicator (-1 for
	/// no indicator).
	sal_Int32 mnLocalInsertIndex;
	/// Index of the first page in the run.
	sal_Int32 mnStartIndex;
	/// Index of the last page in the run.
	sal_Int32 mnEndIndex;
	/// Offset of each item in the run at the start of the current animation.
	::std::vector<Point> maStartOffset;
	/// Target offset of each item in the run at the end of the current animation.
	::std::vector<Point> maEndOffset;
	/// Time at which the current animation started.
	double mnStartTime;

	class Comparator
	{
		public: bool operator() (
			const ::boost::shared_ptr<PageObjectRun>& rpRunA,
			const ::boost::shared_ptr<PageObjectRun>& rpRunB) const
		{
			return rpRunA->mnRunIndex < rpRunB->mnRunIndex;
		}
	};
private:
	controller::Animator::AnimationId mnAnimationId;
	AnimatorAccess& mrAnimatorAccess;
	::boost::function<double(double)> maAccelerationFunction;

	Rectangle GetInnerBoundingBox (
		const view::Layouter& rLayouter,
		const sal_Int32 nIndex) const;
	void RestartAnimation (void);
};
typedef ::boost::shared_ptr<PageObjectRun> SharedPageObjectRun;

Point Blend (const Point& rPointA, const Point& rPointB, const double nT)
{
	return Point(
		sal_Int32(rPointA.X() * (1-nT) + rPointB.X() * nT),
		sal_Int32(rPointA.Y() * (1-nT) + rPointB.Y() * nT));
}

} // end of anonymous namespace

class InsertAnimator::Implementation : public AnimatorAccess
{
public:
	Implementation (SlideSorter& rSlideSorter);
	virtual ~Implementation (void);

	void SetInsertPosition (
		const InsertPosition& rInsertPosition,
		const controller::Animator::AnimationMode eAnimationMode);

	virtual void AddRun (const ::boost::shared_ptr<PageObjectRun> pRun);
	virtual void RemoveRun (const ::boost::shared_ptr<PageObjectRun> pRun);

	virtual model::SlideSorterModel& GetModel (void) const { return mrModel; }
	virtual view::SlideSorterView& GetView (void) const { return mrView; }
	virtual ::boost::shared_ptr<controller::Animator> GetAnimator (void) { return mpAnimator; }
	virtual SharedSdWindow GetContentWindow (void) { return mrSlideSorter.GetContentWindow(); }

private:
	model::SlideSorterModel& mrModel;
	view::SlideSorterView& mrView;
	SlideSorter& mrSlideSorter;
	::boost::shared_ptr<controller::Animator> mpAnimator;
	typedef ::std::set<SharedPageObjectRun, PageObjectRun::Comparator> RunContainer;
	RunContainer maRuns;
	InsertPosition maInsertPosition;

	void StopAnimation (void);
	SharedPageObjectRun GetRun (
		view::Layouter& rLayouter,
		const InsertPosition& rInsertPosition,
		const bool bCreate = true);
	RunContainer::const_iterator FindRun (const sal_Int32 nRunIndex) const;
};

//===== InsertAnimator ========================================================

InsertAnimator::InsertAnimator (SlideSorter& rSlideSorter)
	: mpImplementation(new Implementation(rSlideSorter))
{
}

void InsertAnimator::SetInsertPosition (const InsertPosition& rInsertPosition)
{
	mpImplementation->SetInsertPosition(rInsertPosition, controller::Animator::AM_Animated);
}

void InsertAnimator::Reset (const controller::Animator::AnimationMode eMode)
{
	mpImplementation->SetInsertPosition(InsertPosition(), eMode);
}

//===== InsertAnimator::Implementation ========================================

InsertAnimator::Implementation::Implementation (SlideSorter& rSlideSorter)
	: mrModel(rSlideSorter.GetModel()),
	  mrView(rSlideSorter.GetView()),
	  mrSlideSorter(rSlideSorter),
	  mpAnimator(rSlideSorter.GetController().GetAnimator()),
	  maRuns(),
	  maInsertPosition()
{
}

InsertAnimator::Implementation::~Implementation (void)
{
	SetInsertPosition(InsertPosition(), controller::Animator::AM_Immediate);
}

void InsertAnimator::Implementation::SetInsertPosition (
	const InsertPosition& rInsertPosition,
	const controller::Animator::AnimationMode eMode)
{
	if (maInsertPosition == rInsertPosition)
		return;

	SharedPageObjectRun pOldRun (GetRun(mrView.GetLayouter(), maInsertPosition));
	SharedPageObjectRun pCurrentRun (GetRun(mrView.GetLayouter(), rInsertPosition));
	maInsertPosition = rInsertPosition;

	// When the new insert position is in a different run then move the page
	// objects in the old run to their default positions.
	if (pOldRun != pCurrentRun)
	{
		if (pOldRun)
			pOldRun->ResetOffsets(eMode);
	}

	if (pCurrentRun)
	{
		pCurrentRun->UpdateOffsets(rInsertPosition, mrView.GetLayouter());
	}
}

SharedPageObjectRun InsertAnimator::Implementation::GetRun (
	view::Layouter& rLayouter,
	const InsertPosition& rInsertPosition,
	const bool bCreate)
{
	const sal_Int32 nRow (rInsertPosition.GetRow());
	if (nRow < 0)
		return SharedPageObjectRun();

	RunContainer::const_iterator iRun (maRuns.end());
	if (rLayouter.GetColumnCount() == 1)
	{
		// There is only one run that contains all slides.
		if (maRuns.empty() && bCreate)
			maRuns.insert(SharedPageObjectRun(new PageObjectRun(
				*this,
				0,
				0,
				mrModel.GetPageCount()-1)));
		iRun = maRuns.begin();
	}
	else
	{
		iRun = FindRun(nRow);
		if (iRun == maRuns.end() && bCreate)
		{
			// Create a new run.
			const sal_Int32 nStartIndex (rLayouter.GetIndex(nRow, 0));
			const sal_Int32 nEndIndex (rLayouter.GetIndex(nRow, rLayouter.GetColumnCount()-1));
			if (nStartIndex <= nEndIndex)
			{
				iRun = maRuns.insert(SharedPageObjectRun(new PageObjectRun(
					*this,
					nRow,
					nStartIndex,
					nEndIndex))).first;
				OSL_ASSERT(iRun != maRuns.end());
			}
		}
	}

	if (iRun != maRuns.end())
		return *iRun;
	else
		return SharedPageObjectRun();
}

InsertAnimator::Implementation::RunContainer::const_iterator
	InsertAnimator::Implementation::FindRun (const sal_Int32 nRunIndex) const
{
	return std::find_if(
		maRuns.begin(),
		maRuns.end(),
		::boost::bind(
			::std::equal_to<sal_Int32>(),
			::boost::bind(&PageObjectRun::mnRunIndex, _1),
			nRunIndex));
}

void InsertAnimator::Implementation::AddRun (const ::boost::shared_ptr<PageObjectRun> pRun)
{
	if (pRun)
	{
		maRuns.insert(pRun);
	}
	else
	{
		OSL_ASSERT(pRun);
	}
}

void InsertAnimator::Implementation::RemoveRun (const ::boost::shared_ptr<PageObjectRun> pRun)
{
	if (pRun)
	{
		// Do not remove runs that show the space for the insertion indicator.
		if (pRun->mnLocalInsertIndex == -1)
		{
			InsertAnimator::Implementation::RunContainer::const_iterator iRun (FindRun(pRun->mnRunIndex));
			if (iRun != maRuns.end())
			{
				OSL_ASSERT(*iRun == pRun);
				maRuns.erase(iRun);
			}
		}
	}
	else
	{
		OSL_ASSERT(pRun);
	}
}

//===== PageObjectRun =========================================================

PageObjectRun::PageObjectRun (
	AnimatorAccess& rAnimatorAccess,
	const sal_Int32 nRunIndex,
	const sal_Int32 nStartIndex,
	const sal_Int32 nEndIndex)
	: mnRunIndex(nRunIndex),
	  mnLocalInsertIndex(-1),
	  mnStartIndex(nStartIndex),
	  mnEndIndex(nEndIndex),
	  maStartOffset(),
	  maEndOffset(),
	  mnStartTime(-1),
	  mnAnimationId(controller::Animator::NotAnAnimationId),
	  mrAnimatorAccess(rAnimatorAccess),
	  maAccelerationFunction(
		controller::AnimationParametricFunction(
			controller::AnimationBezierFunction (0.1,0.7)))
{
	maStartOffset.resize(nEndIndex - nStartIndex + 1);
	maEndOffset.resize(nEndIndex - nStartIndex + 1);
}

PageObjectRun::~PageObjectRun (void)
{
}

Rectangle PageObjectRun::GetInnerBoundingBox (
	const view::Layouter& rLayouter,
	const sal_Int32 nIndex) const
{
	model::SharedPageDescriptor pDescriptor (
		mrAnimatorAccess.GetModel().GetPageDescriptor(nIndex));
	if (pDescriptor)
		if (pDescriptor->HasState(model::PageDescriptor::ST_Selected))
			return rLayouter.GetPageObjectLayouter()->GetBoundingBox(
				pDescriptor,
				PageObjectLayouter::PageObject,
				PageObjectLayouter::ModelCoordinateSystem);
		else
			return rLayouter.GetPageObjectLayouter()->GetBoundingBox(
				pDescriptor,
				PageObjectLayouter::Preview,
				PageObjectLayouter::ModelCoordinateSystem);
	else
		return Rectangle();
}

void PageObjectRun::UpdateOffsets(
	const InsertPosition& rInsertPosition,
	const view::Layouter& rLayouter)
{
	const bool bIsVertical (rLayouter.GetColumnCount()==1);
	const sal_Int32 nLocalInsertIndex(bIsVertical
		? rInsertPosition.GetRow()
		: rInsertPosition.GetColumn());
	if (nLocalInsertIndex != mnLocalInsertIndex)
	{
		mnLocalInsertIndex = nLocalInsertIndex;

		model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel());
		const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1);
		for (sal_Int32 nIndex=0; nIndex<nRunLength; ++nIndex)
		{
			model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex));
			if (pDescriptor)
				maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset();
			maEndOffset[nIndex] = nIndex < mnLocalInsertIndex
				? rInsertPosition.GetLeadingOffset()
				: rInsertPosition.GetTrailingOffset();
			if (bIsVertical)
				maEndOffset[nIndex].X() = 0;
			else
				maEndOffset[nIndex].Y() = 0;
		}
		RestartAnimation();
	}
}

void PageObjectRun::ResetOffsets (const controller::Animator::AnimationMode eMode)
{
	mnLocalInsertIndex = -1;
	const sal_Int32 nRunLength (mnEndIndex - mnStartIndex + 1);
	model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel());
	view::SlideSorterView& rView (mrAnimatorAccess.GetView());
	for (sal_Int32 nIndex=0; nIndex<nRunLength; ++nIndex)
	{
		model::SharedPageDescriptor pDescriptor(rModel.GetPageDescriptor(nIndex+mnStartIndex));
		if (pDescriptor)
		{
			if (eMode == controller::Animator::AM_Animated)
				maStartOffset[nIndex] = pDescriptor->GetVisualState().GetLocationOffset();
			else
			{
				const Rectangle aOldBoundingBox (pDescriptor->GetBoundingBox());
				pDescriptor->GetVisualState().SetLocationOffset(Point(0,0));
				rView.RequestRepaint(aOldBoundingBox);
				rView.RequestRepaint(pDescriptor);
			}
		}
		maEndOffset[nIndex] = Point(0,0);
	}
	if (eMode == controller::Animator::AM_Animated)
		RestartAnimation();
	else
		mrAnimatorAccess.RemoveRun(shared_from_this());
}

void PageObjectRun::RestartAnimation (void)
{
	// Stop the current animation.
	if (mnAnimationId != controller::Animator::NotAnAnimationId)
	{
		mrAnimatorAccess.GetAnimator()->RemoveAnimation(mnAnimationId);
	}

	// Restart the animation.
	mrAnimatorAccess.AddRun(shared_from_this());
	mnAnimationId = mrAnimatorAccess.GetAnimator()->AddAnimation(
		::boost::ref(*this),
		0,
		300,
		::boost::bind(
			&AnimatorAccess::RemoveRun,
			::boost::ref(mrAnimatorAccess),
			shared_from_this()));
}

void PageObjectRun::operator () (const double nGlobalTime)
{
	if (mnStartTime < 0)
		mnStartTime = nGlobalTime;

	double nLocalTime (nGlobalTime - mnStartTime);
	if (nLocalTime > 1.0)
		nLocalTime = 1.0;
	nLocalTime = maAccelerationFunction(nLocalTime);

	model::SlideSorterModel& rModel (mrAnimatorAccess.GetModel());
	view::SlideSorterView& rView (mrAnimatorAccess.GetView());
	for (sal_Int32 nIndex=mnStartIndex; nIndex<=mnEndIndex; ++nIndex)
	{
		model::SharedPageDescriptor pDescriptor (rModel.GetPageDescriptor(nIndex));
		if ( ! pDescriptor)
			continue;
		const Rectangle aOldBoundingBox (pDescriptor->GetBoundingBox());
		pDescriptor->GetVisualState().SetLocationOffset(
			Blend(
				maStartOffset[nIndex-mnStartIndex],
				maEndOffset[nIndex-mnStartIndex],
				nLocalTime));

		// Request a repaint of the old and new bounding box (which largely overlap.)
		rView.RequestRepaint(aOldBoundingBox);
		rView.RequestRepaint(pDescriptor);
	}

	// Call Flush to make
	// a) animations a bit more smooth and
	// b) on Mac without the Flush a Reset of the page locations is not properly
	// visualized when the mouse leaves the window during drag-and-drop.
	mrAnimatorAccess.GetContentWindow()->Flush();
}

} } } // end of namespace ::sd::slidesorter::view

ext: cxx

max_stars_repo_name: Alan-love/openoffice

max_issues_repo_name: Alan-love/openoffice

max_forks_repo_name: Alan-love/openoffice