<commit_before>#include <fstream>
#include <util.h>
#include <stdio.h>
#include <common.h>
#include <errlog.h>
#include <option.h>
#include <callback.h>
#include "sqlite3pp.h"

static uint8_t empty[kSHA256ByteSize] = { 0x42 };

typedef GoogMap<
    Hash256,
    uint64_t,
    Hash256Hasher,
    Hash256Equal
    >::Map OutputMap;

inline bool file_exists(const std::string& name)
{
  std::ifstream file(name);

  return file.good();
}

static void writeHexEscapedBinaryBuffer(
  FILE          *f,
  const uint8_t *p,
  size_t         n
  )
{
  char buf[3];

  p += n;

  while (n--)
  {
    uint8_t c = *(--p);
    sprintf(buf, "%02X", (unsigned char)c);
    fputs(buf, f);
  }
}

struct SQLDump : public Callback {
  FILE *txFile;
  FILE *blockFile;
  FILE *inputFile;
  FILE *outputFile;

  uint64_t               txID;
  uint64_t               blkID;
  uint64_t               inputID;
  uint64_t               outputID;
  uint64_t               firstBlock;
  uint64_t               lastBlock;
  OutputMap              outputMap;
  optparse::OptionParser parser;

  SQLDump() {
    parser
    .usage("[options]")
    .version("")
    .description("create an SQL dump of the blockchain")
    .epilog("")
    ;
    parser
    .add_option("-a", "--atBlock")
    .action("store")
    .type("int")
    .set_default(-1)
    .help("stop dump at block <block> (default: all)")
    ;
  }

  virtual const char* name() const {
    return "sqldump";
  }

  virtual const optparse::OptionParser* optionParser() const {
    return &parser;
  }

  virtual bool needUpstream() const {
    return true;
  }

  virtual void aliases(
    std::vector<const char *>& v
    ) const {
    v.push_back("dump");
  }

  virtual int init(
    int         argc,
    const char *argv[]
    ) {
    txID     = 0;
    blkID    = 0;
    inputID  = 0;
    outputID = 0;

    static uint64_t sz = 32 * 1000 * 1000;
    outputMap.setEmptyKey(empty);
    outputMap.resize(sz);

    optparse::Values& values = parser.parse_args(argc, argv);

    if (values.is_set_by_user("atBlock")) {
      lastBlock = values.get("atBlock").asUInt64();
      info("Last block: %" PRIu64 ".\n", lastBlock);
    } else {
      lastBlock = 0;
    }

    if (!file_exists("../blockchain/blockchain.sqlite"))
    {
      firstBlock = 0;
    }
    else
    {
      sqlite3pp::database db("../blockchain/blockchain.sqlite");
      sqlite3pp::query    qry(db, "SELECT MAX(block_id) FROM blocks");

      sqlite3pp::query::iterator i = qry.begin();

      firstBlock = (uint64_t)atoi((*i).get<char const *>(0)) + 1;

      info("Resuming from block %" PRIu64 ".\n", firstBlock);
    }

    info("Dumping the blockchain...");

    txFile = fopen("tx.txt", "w");

    if (!txFile) sysErrFatal("couldn't open file txs.txt for writing\n");

    blockFile = fopen("blocks.txt", "w");

    if (!blockFile) sysErrFatal("couldn't open file blocks.txt for writing\n");

    inputFile = fopen("txin.txt", "w");

    if (!inputFile) sysErrFatal("couldn't open file inputs.txt for writing\n");

    outputFile = fopen("txout.txt", "w");

    if (!outputFile) sysErrFatal("couldn't open file outputs.txt for writing\n");

    FILE *sqlFile = fopen("blockchain.sql", "w");

    if (!sqlFile) sysErrFatal("couldn't open file blockchain.sql for writing\n");

    fprintf(
      sqlFile,
      "PRAGMA journal_mode=MEMORY;\n"
      "PRAGMA synchronous=NORMAL;\n"
      "CREATE TABLE IF NOT EXISTS blocks(\n"
      "    block_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    block_hash TEXT NOT NULL,\n"
      "    time BIGINT NOT NULL\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS tx(\n"
      "    tx_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    tx_hash TEXT NOT NULL,\n"
      "    block_id BIGINT NOT NULL,\n"
      "    FOREIGN KEY (block_id) REFERENCES blocks (block_id)\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS txout(\n"
      "    txout_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    address CHAR(40),\n"
      "    txout_value BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txout_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS txin(\n"
      "    txin_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    txout_id BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txin_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "CREATE INDEX IF NOT EXISTS x_txin_txout ON txin (txout_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txin_txid ON txin (tx_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txout_txid ON txout (tx_id);\n"
      "CREATE VIEW IF NOT EXISTS tx_full AS SELECT blocks.time, tx.tx_hash, tx.tx_id, txout.address, txout.txout_value FROM txout LEFT JOIN tx ON (tx.tx_id = txout.tx_id) LEFT JOIN blocks ON (tx.block_id = blocks.block_id);\n"
      "\n"
      );
    fclose(sqlFile);

    FILE *bashFile = fopen("blockchain.sh", "w");

    if (!bashFile) sysErrFatal("Couldn't open file blockchain.sh for writing!\n");

    fprintf(
      bashFile,
      "echo 'Recreating DB blockchain...'\n"
      "mkdir ../blockchain\n"
      "sqlite3 ../blockchain/blockchain.sqlite < blockchain.sql\n"
      "rm -f blockchain.sql\n"
      "echo done.\n"
      "for i in blocks txin txout tx\n"
      "do\n"
      "    echo \"Importing table ${i}...\"\n"
      "    echo \".import $i.txt $i\" | sqlite3 ../blockchain/blockchain.sqlite\n"
      "    echo done.\n"
      "    rm -f $i.txt\n"
      "    echo\n"
      "done\n"
      "rm -f blockchain.sh\n"
      "\n"
      );
    fclose(bashFile);

    return 0;
  }

  virtual void startBlock(
    const Block *b,
    uint64_t
    ) {
    if (lastBlock > 0 && lastBlock < static_cast<uint64_t>(b->height)) {
      wrapup();
    }

    auto p = b->chunk->getData();
    uint8_t blockHash[kSHA256ByteSize];
    sha256Twice(blockHash, p, 80);

    SKIP(uint32_t,  version,       p);
    SKIP(uint256_t, prevBlkHash,   p);
    SKIP(uint256_t, blkMerkleRoot, p);
    LOAD(uint32_t, blkTime, p);

    blkID = b->height - 1;

    if (blkID >= firstBlock) {
      fprintf(blockFile, "%" PRIu64 "|", blkID);

      writeHexEscapedBinaryBuffer(blockFile, blockHash, kSHA256ByteSize);
      fputc('|', blockFile);
      fprintf(blockFile, "%" PRIu64 "\n", (uint64_t)blkTime);
    }

    if (0 == blkID % 5000) {
      fprintf(
        stderr,
        "block=%8" PRIu64 " "
        "nbOutputs=%9" PRIu64 "\n",
        blkID,
        outputMap.size()
        );
    }
  }

  virtual void startTX(
    const uint8_t *p,
    const uint8_t *hash
    ) {
    if (blkID >= firstBlock) {
      fprintf(txFile, "%" PRIu64 "|", txID);

      writeHexEscapedBinaryBuffer(txFile, hash, kSHA256ByteSize);
      fputc('|', txFile);

      fprintf(txFile, "%" PRIu64 "\n", blkID);
    }
    txID++;
  }

  virtual void endOutput(
    const uint8_t *p,
    uint64_t       value,
    const uint8_t *txHash,
    uint64_t       outputIndex,
    const uint8_t *outputScript,
    uint64_t       outputScriptSize
    ) {
    uint8_t address[40];

    address[0] = 'X';
    address[1] = 0;

    uint8_t   addrType[3];
    uint160_t pubKeyHash;
    int type = solveOutputScript(
      pubKeyHash.v,
      outputScript,
      outputScriptSize,
      addrType
      );

    if (likely(0 <= type)) {
      hash160ToAddr(
        address,
        pubKeyHash.v,
        false,
        addrType[0]
        );
    }

    if (blkID >= firstBlock) {
      fprintf(
        outputFile,
        "%" PRIu64 "|"
        "%s|"
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu32 "\n"
        ,
        outputID,
        address,
        value,
        txID,
        (uint32_t)outputIndex
        );
    }

    uint32_t oi = outputIndex;
    uint8_t *h  = allocHash256();
    memcpy(h, txHash, kSHA256ByteSize);

    uintptr_t ih  = reinterpret_cast<uintptr_t>(h);
    uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
    h32[0] ^= oi;

    outputMap[h] = outputID++;
  }

  virtual void edge(
    uint64_t       value,
    const uint8_t *upTXHash,
    uint64_t       outputIndex,
    const uint8_t *outputScript,
    uint64_t       outputScriptSize,
    const uint8_t *downTXHash,
    uint64_t       inputIndex,
    const uint8_t *inputScript,
    uint64_t       inputScriptSize
    ) {
    uint256_t h;
    uint32_t  oi = outputIndex;

    memcpy(h.v, upTXHash, kSHA256ByteSize);

    uintptr_t ih  = reinterpret_cast<uintptr_t>(h.v);
    uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
    h32[0] ^= oi;

    auto src = outputMap.find(h.v);

    if (outputMap.end() == src) {
      errFatal("Unconnected input.");
    }

    if (blkID >= firstBlock) {
      fprintf(
        inputFile,
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu32 "\n"
        ,
        inputID++,
        src->second,
        txID,
        (uint32_t)inputIndex
        );
    } else {
      inputID++;
    }
  }

  virtual void wrapup() {
    fclose(outputFile);
    fclose(inputFile);
    fclose(blockFile);
    fclose(txFile);
    system("/bin/bash ./blockchain.sh");
    info("Done.");
    exit(0);
  }
};

static SQLDump sqlDump;
<commit_msg>Add indexes after mass importing.<commit_after>#include <fstream>
#include <util.h>
#include <stdio.h>
#include <common.h>
#include <errlog.h>
#include <option.h>
#include <callback.h>
#include "sqlite3pp.h"

static uint8_t empty[kSHA256ByteSize] = { 0x42 };

typedef GoogMap<
    Hash256,
    uint64_t,
    Hash256Hasher,
    Hash256Equal
    >::Map OutputMap;

inline bool file_exists(const std::string& name)
{
  std::ifstream file(name);

  return file.good();
}

static void writeHexEscapedBinaryBuffer(
  FILE          *f,
  const uint8_t *p,
  size_t         n
  )
{
  char buf[3];

  p += n;

  while (n--)
  {
    uint8_t c = *(--p);
    sprintf(buf, "%02X", (unsigned char)c);
    fputs(buf, f);
  }
}

struct SQLDump : public Callback {
  FILE *txFile;
  FILE *blockFile;
  FILE *inputFile;
  FILE *outputFile;

  uint64_t               txID;
  uint64_t               blkID;
  uint64_t               inputID;
  uint64_t               outputID;
  uint64_t               firstBlock;
  uint64_t               lastBlock;
  OutputMap              outputMap;
  optparse::OptionParser parser;

  SQLDump() {
    parser
    .usage("[options]")
    .version("")
    .description("create an SQL dump of the blockchain")
    .epilog("")
    ;
    parser
    .add_option("-a", "--atBlock")
    .action("store")
    .type("int")
    .set_default(-1)
    .help("stop dump at block <block> (default: all)")
    ;
  }

  virtual const char* name() const {
    return "sqldump";
  }

  virtual const optparse::OptionParser* optionParser() const {
    return &parser;
  }

  virtual bool needUpstream() const {
    return true;
  }

  virtual void aliases(
    std::vector<const char *>& v
    ) const {
    v.push_back("dump");
  }

  virtual int init(
    int         argc,
    const char *argv[]
    ) {
    txID     = 0;
    blkID    = 0;
    inputID  = 0;
    outputID = 0;

    static uint64_t sz = 32 * 1000 * 1000;
    outputMap.setEmptyKey(empty);
    outputMap.resize(sz);

    optparse::Values& values = parser.parse_args(argc, argv);

    if (values.is_set_by_user("atBlock")) {
      lastBlock = values.get("atBlock").asUInt64();
      info("Last block: %" PRIu64 ".\n", lastBlock);
    } else {
      lastBlock = 0;
    }

    if (!file_exists("../blockchain/blockchain.sqlite"))
    {
      firstBlock = 0;
    }
    else
    {
      sqlite3pp::database db("../blockchain/blockchain.sqlite");
      sqlite3pp::query    qry(db, "SELECT MAX(block_id) FROM blocks");

      sqlite3pp::query::iterator i = qry.begin();

      firstBlock = (uint64_t)atoi((*i).get<char const *>(0)) + 1;

      info("Resuming from block %" PRIu64 ".\n", firstBlock);
    }

    info("Dumping the blockchain...");

    txFile = fopen("tx.txt", "w");

    if (!txFile) sysErrFatal("couldn't open file txs.txt for writing\n");

    blockFile = fopen("blocks.txt", "w");

    if (!blockFile) sysErrFatal("couldn't open file blocks.txt for writing\n");

    inputFile = fopen("txin.txt", "w");

    if (!inputFile) sysErrFatal("couldn't open file inputs.txt for writing\n");

    outputFile = fopen("txout.txt", "w");

    if (!outputFile) sysErrFatal("couldn't open file outputs.txt for writing\n");

    FILE *sqlFile = fopen("blockchain.sql", "w");

    if (!sqlFile) sysErrFatal("couldn't open file blockchain.sql for writing\n");

    FILE *indexesSqlFile = fopen("blockchain_indexes.sql", "w");

    if (!indexesSqlFile) sysErrFatal("couldn't open file blockchain_indexes.sql for writing\n");

    fprintf(
      sqlFile,
      "PRAGMA journal_mode=MEMORY;\n"
      "PRAGMA synchronous=NORMAL;\n"
      "CREATE TABLE IF NOT EXISTS blocks(\n"
      "    block_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    block_hash TEXT NOT NULL,\n"
      "    time BIGINT NOT NULL\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS tx(\n"
      "    tx_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    tx_hash TEXT NOT NULL,\n"
      "    block_id BIGINT NOT NULL,\n"
      "    FOREIGN KEY (block_id) REFERENCES blocks (block_id)\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS txout(\n"
      "    txout_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    address CHAR(40),\n"
      "    txout_value BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txout_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "CREATE TABLE IF NOT EXISTS txin(\n"
      "    txin_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    txout_id BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txin_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "CREATE VIEW IF NOT EXISTS tx_full AS SELECT blocks.time, tx.tx_hash, tx.tx_id, txout.address, txout.txout_value FROM txout LEFT JOIN tx ON (tx.tx_id = txout.tx_id) LEFT JOIN blocks ON (tx.block_id = blocks.block_id);\n"
      );
    fclose(sqlFile);

    fprintf(
      indexesSqlFile,
      "CREATE INDEX IF NOT EXISTS x_txin_txout ON txin (txout_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txin_txid ON txin (tx_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txout_txid ON txout (tx_id);\n"
      );
    fclose(indexesSqlFile);

    FILE *bashFile = fopen("blockchain.sh", "w");

    if (!bashFile) sysErrFatal("Couldn't open file blockchain.sh for writing!\n");

    fprintf(
      bashFile,
      "echo 'Recreating DB blockchain...'\n"
      "mkdir ../blockchain\n"
      "sqlite3 ../blockchain/blockchain.sqlite < blockchain.sql\n"
      "rm -f blockchain.sql\n"
      "echo done.\n"
      "for i in blocks txin txout tx\n"
      "do\n"
      "    echo \"Importing table ${i}...\"\n"
      "    echo \".import $i.txt $i\" | sqlite3 ../blockchain/blockchain.sqlite\n"
      "    echo done.\n"
      "    rm -f $i.txt\n"
      "    echo\n"
      "echo '(Re)creating indexes...'\n"
      "sqlite3 ../blockchain/blockchain.sqlite < blockchain_indexes.sql\n"
      "rm -f blockchain_indexes.sql\n"
      "done\n"
      "rm -f blockchain.sh\n"
      );
    fclose(bashFile);

    return 0;
  }

  virtual void startBlock(
    const Block *b,
    uint64_t
    ) {
    if (lastBlock > 0 && lastBlock < static_cast<uint64_t>(b->height)) {
      wrapup();
    }

    auto p = b->chunk->getData();
    uint8_t blockHash[kSHA256ByteSize];
    sha256Twice(blockHash, p, 80);

    SKIP(uint32_t,  version,       p);
    SKIP(uint256_t, prevBlkHash,   p);
    SKIP(uint256_t, blkMerkleRoot, p);
    LOAD(uint32_t, blkTime, p);

    blkID = b->height - 1;

    if (blkID >= firstBlock) {
      fprintf(blockFile, "%" PRIu64 "|", blkID);

      writeHexEscapedBinaryBuffer(blockFile, blockHash, kSHA256ByteSize);
      fputc('|', blockFile);
      fprintf(blockFile, "%" PRIu64 "\n", (uint64_t)blkTime);
    }

    if (0 == blkID % 5000) {
      fprintf(
        stderr,
        "block=%8" PRIu64 " "
        "nbOutputs=%9" PRIu64 "\n",
        blkID,
        outputMap.size()
        );
    }
  }

  virtual void startTX(
    const uint8_t *p,
    const uint8_t *hash
    ) {
    if (blkID >= firstBlock) {
      fprintf(txFile, "%" PRIu64 "|", txID);

      writeHexEscapedBinaryBuffer(txFile, hash, kSHA256ByteSize);
      fputc('|', txFile);

      fprintf(txFile, "%" PRIu64 "\n", blkID);
    }
    txID++;
  }

  virtual void endOutput(
    const uint8_t *p,
    uint64_t       value,
    const uint8_t *txHash,
    uint64_t       outputIndex,
    const uint8_t *outputScript,
    uint64_t       outputScriptSize
    ) {
    uint8_t address[40];

    address[0] = 'X';
    address[1] = 0;

    uint8_t   addrType[3];
    uint160_t pubKeyHash;
    int type = solveOutputScript(
      pubKeyHash.v,
      outputScript,
      outputScriptSize,
      addrType
      );

    if (likely(0 <= type)) {
      hash160ToAddr(
        address,
        pubKeyHash.v,
        false,
        addrType[0]
        );
    }

    if (blkID >= firstBlock) {
      fprintf(
        outputFile,
        "%" PRIu64 "|"
        "%s|"
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu32 "\n"
        ,
        outputID,
        address,
        value,
        txID,
        (uint32_t)outputIndex
        );
    }

    uint32_t oi = outputIndex;
    uint8_t *h  = allocHash256();
    memcpy(h, txHash, kSHA256ByteSize);

    uintptr_t ih  = reinterpret_cast<uintptr_t>(h);
    uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
    h32[0] ^= oi;

    outputMap[h] = outputID++;
  }

  virtual void edge(
    uint64_t       value,
    const uint8_t *upTXHash,
    uint64_t       outputIndex,
    const uint8_t *outputScript,
    uint64_t       outputScriptSize,
    const uint8_t *downTXHash,
    uint64_t       inputIndex,
    const uint8_t *inputScript,
    uint64_t       inputScriptSize
    ) {
    uint256_t h;
    uint32_t  oi = outputIndex;

    memcpy(h.v, upTXHash, kSHA256ByteSize);

    uintptr_t ih  = reinterpret_cast<uintptr_t>(h.v);
    uint32_t *h32 = reinterpret_cast<uint32_t *>(ih);
    h32[0] ^= oi;

    auto src = outputMap.find(h.v);

    if (outputMap.end() == src) {
      errFatal("Unconnected input.");
    }

    if (blkID >= firstBlock) {
      fprintf(
        inputFile,
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu64 "|"
        "%" PRIu32 "\n"
        ,
        inputID++,
        src->second,
        txID,
        (uint32_t)inputIndex
        );
    } else {
      inputID++;
    }
  }

  virtual void wrapup() {
    fclose(outputFile);
    fclose(inputFile);
    fclose(blockFile);
    fclose(txFile);
    system("/bin/bash ./blockchain.sh");
    info("Done.");
    exit(0);
  }
};

static SQLDump sqlDump;
<|endoftext|>


<commit_before>/*=========================================================================

  Library   : Image Registration Toolkit (IRTK)
  Module    : $Id$
  Copyright : Imperial College, Department of Computing
              Visual Information Processing (VIP), 2008 onwards
  Date      : $Date$
  Version   : $Revision$
  Changes   : $Author$

=========================================================================*/

#include <irtkImage.h>

#include <irtkTransformation.h>

#ifdef HAS_VTK

#include <vtkPolyDataWriter.h>
#include <vtkPolyDataReader.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>

// Default filenames
char *input_name = NULL, *output_name = NULL;
char *dof_name  = NULL;

void usage()
{
  cerr << "Usage: ptransformation [input] [output] <options>\n"
       << endl;
  cerr << "<-dofin file>      Transformation" << endl;
  cerr << "<-invert>          Invert transformation" << endl;
  cerr << "<-source image>    reference source image" << endl;
  cerr << "<-target image>    reference target image" << endl;
  cerr << "<-partial number>  Transform 0-number points copy rest"<<endl;
  exit(1);
}

int main(int argc, char **argv)
{
  int ok, invert,sourceon,targeton, pnumber;
  irtkPointSet output, input;
  irtkTransformation *transformation;
  irtkGreyImage target,source;

  // Check command line
  if (argc < 3) {
    usage();
  }
  pnumber = 0;

  // Parse input and output point lists
  input_name = argv[1];
  argc--;
  argv++;
  output_name = argv[1];
  argc--;
  argv++;

  // Default parameters
  invert = false;
  targeton = false;
  sourceon = false;

  // Parse arguments
  while (argc > 1) {
    ok = false;
    if ((ok == false) && (strcmp(argv[1], "-dofin") == 0)) {
      argc--;
      argv++;
      dof_name = argv[1];
      argc--;
      argv++;
      ok = true;
    }
    if ((ok == false) && (strcmp(argv[1], "-invert") == 0)) {
      argc--;
      argv++;
      invert = true;
      ok = true;
    }
	if ((ok == false) && (strcmp(argv[1], "-source") == 0)) {
      argc--;
      argv++;
      ok = true;
	  sourceon = true;
	  source.Read(argv[1]);
	  argc--;
      argv++;
    }
	if ((ok == false) && (strcmp(argv[1], "-target") == 0)) {
		argc--;
		argv++;
		targeton = true;
		target.Read(argv[1]);
		ok = true;
		argc--;
		argv++;
    }
	if ((ok == false) && (strcmp(argv[1], "-partial") == 0)) {
		argc--;
		argv++;
		pnumber = atoi(argv[1]);
		ok = true;
		argc--;
		argv++;
    }
    if (ok == false) {
      cerr << "Can not parse argument " << argv[1] << endl;
      usage();
    }
  }

  if (dof_name != NULL) {
    // Read transformation
    transformation = irtkTransformation::New(dof_name);
  } else {
    // Create identity transformation
    transformation = new irtkRigidTransformation;
  }

  // Read point lists
  vtkPolyDataReader *reader = vtkPolyDataReader::New();
  reader->SetFileName(input_name);
  reader->Update();

  vtkPolyData* surface = reader->GetOutput();
  vtkPoints*   points  = surface->GetPoints();

  for (int i=0; i < points->GetNumberOfPoints(); i++) {
    double p[3];
    points->GetPoint(i,p);
	if(sourceon&&targeton){
		target.WorldToImage(p[0],p[1],p[2]);
		//p[1] = target.GetY() - p[1];
		source.ImageToWorld(p[0],p[1],p[2]);
	}
	if(i<pnumber || pnumber == 0){
		if (invert == false) {
			transformation->Transform(p[0],p[1],p[2]);
		} else {
			transformation->Inverse(p[0],p[1],p[2]);
		}
	}
    points->SetPoint(i,p);
  }

  // Write the final set
  vtkPolyDataWriter   *writer = vtkPolyDataWriter::New();
  writer->SetFileName(output_name);
  writer->SetInput(surface);
  writer->Write();
}

#else
#include <irtkCommon.h>
int main(int argc, char **argv)
{
  cerr << "ptransformation: this program needs to be compiled with vtk enabled.\n";
  return 0;
}
#endif
<commit_msg>Tidied up and clarified code. Not sure why the source and target image options are needed but left them in.<commit_after>/*=========================================================================

  Library   : Image Registration Toolkit (IRTK)
  Module    : $Id$
  Copyright : Imperial College, Department of Computing
              Visual Information Processing (VIP), 2008 onwards
  Date      : $Date$
  Version   : $Revision$
  Changes   : $Author$

=========================================================================*/

#include <irtkImage.h>

#include <irtkTransformation.h>

#ifdef HAS_VTK

#include <vtkPolyDataWriter.h>
#include <vtkPolyDataReader.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>

// Default filenames
char *input_name = NULL, *output_name = NULL;
char *dof_name  = NULL;

void usage()
{
  cerr << "Usage: ptransformation [input] [output] <options>\n"
       << endl;
  cerr << "<-dofin file>      Transformation" << endl;
  cerr << "<-invert>          Invert transformation" << endl;
  cerr << "<-source image>    reference source image" << endl;
  cerr << "<-target image>    reference target image" << endl;
  cerr << "<-partial number>  Transform 0-number points copy rest"<<endl;
  exit(1);
}

int main(int argc, char **argv)
{
  int ok, invert,sourceGiven,targetGiven, noOfPointsToTransform;
  irtkPointSet output, input;
  irtkTransformation *transformation;
  irtkGreyImage target,source;

  // Check command line
  if (argc < 3) {
    usage();
  }

  // Setting this to zero actually defaults to transforming all the points in the input file.
  noOfPointsToTransform = 0;

  // Parse input and output point lists
  input_name = argv[1];
  argc--;
  argv++;
  output_name = argv[1];
  argc--;
  argv++;

  // Default parameters
  invert = false;
  targetGiven = false;
  sourceGiven = false;

  // Parse arguments
  while (argc > 1) {
    ok = false;
    if ((ok == false) && (strcmp(argv[1], "-dofin") == 0)) {
      argc--;
      argv++;
      dof_name = argv[1];
      argc--;
      argv++;
      ok = true;
    }
    if ((ok == false) && (strcmp(argv[1], "-invert") == 0)) {
      argc--;
      argv++;
      invert = true;
      ok = true;
    }
	if ((ok == false) && (strcmp(argv[1], "-source") == 0)) {
      argc--;
      argv++;
      ok = true;
	  sourceGiven = true;
	  source.Read(argv[1]);
	  argc--;
      argv++;
    }
	if ((ok == false) && (strcmp(argv[1], "-target") == 0)) {
		argc--;
		argv++;
		targetGiven = true;
		target.Read(argv[1]);
		ok = true;
		argc--;
		argv++;
    }
	if ((ok == false) && (strcmp(argv[1], "-partial") == 0)) {
		argc--;
		argv++;
		noOfPointsToTransform = atoi(argv[1]);
		ok = true;
		argc--;
		argv++;
    }
    if (ok == false) {
      cerr << "Can not parse argument " << argv[1] << endl;
      usage();
    }
  }

  if (dof_name != NULL) {
    // Read transformation
    transformation = irtkTransformation::New(dof_name);
  } else {
    // Create identity transformation
    transformation = new irtkRigidTransformation;
  }

  // Read point lists
  vtkPolyDataReader *reader = vtkPolyDataReader::New();
  reader->SetFileName(input_name);
  reader->Update();

  vtkPolyData* surface = reader->GetOutput();
  vtkPoints*   points  = surface->GetPoints();
  double p[3];

  for (int i=0; i < points->GetNumberOfPoints(); i++) {

    points->GetPoint(i,p);

    if(sourceGiven && targetGiven){
      target.WorldToImage(p[0],p[1],p[2]);
      source.ImageToWorld(p[0],p[1],p[2]);
    }

    if(i < noOfPointsToTransform || noOfPointsToTransform == 0){

      if (invert == false) {
        transformation->Transform(p[0],p[1],p[2]);
      } else {
        transformation->Inverse(p[0],p[1],p[2]);
      }
    }

    points->SetPoint(i,p);
  }

  // Write the final set
  vtkPolyDataWriter   *writer = vtkPolyDataWriter::New();
  writer->SetFileName(output_name);
  writer->SetInput(surface);
  writer->Write();
}

#else
#include <irtkCommon.h>
int main(int argc, char **argv)
{
  cerr << "ptransformation: this program needs to be compiled with vtk enabled.\n";
  return 0;
}
#endif
<|endoftext|>


<commit_before>// Authors: Axel Naumann, Philippe Canal, Danilo Piparo

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_STAGE1_BUILD
#include "rootclingTCling.h"
#include "rootclingIO.h"
#endif

#include "rootcling_impl.h"
#include "RConfigure.h"
#include "RConfig.h"

#include <iostream>

#ifdef _WIN32
# ifdef system
#  undef system
# endif
# include <windows.h>
# include <Tlhelp32.h> // for MAX_MODULE_NAME32
# include <process.h>
# define PATH_MAX _MAX_PATH
# ifdef interface
// prevent error coming from clang/AST/Attrs.inc
#  undef interface
# endif
#else // _WIN32
# include <limits.h>
# include <unistd.h>
# include <dlfcn.h>
#endif

#ifdef __APPLE__
#include <libgen.h> // Needed for basename
#include <mach-o/dyld.h>
#endif

extern "C" {
R__DLLEXPORT void usedToIdentifyRootClingByDlSym() {}
}

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

#ifdef __ICC
#pragma warning disable 69
#endif

ROOT::Internal::RootCling::TROOTSYSSetter gROOTSYSSetter;

int main(int argc, char **argv)
{
   // Force the emission of the symbol - the compiler cannot know that argv
   // is always set.
   if (!argv) {
      auto dummyVal =  (int)(long)&usedToIdentifyRootClingByDlSym;
      return dummyVal;
   }

   ROOT::Internal::RootCling::DriverConfig config{};
#ifdef R__HAVE_LLVMRESOURCEDIR
  config.fLLVMResourceDir= "@R__LLVMRESOURCEDIR@";
#endif

#ifdef ROOT_STAGE1_BUILD
   config.fBuildingROOTStage1 = true;
#else
   config.fBuildingROOTStage1 = false;
   config.fTROOT__GetExtraInterpreterArgs = &TROOT__GetExtraInterpreterArgs;
   config.fTCling__GetInterpreter = &TCling__GetInterpreter;
   config.fInitializeStreamerInfoROOTFile = &InitializeStreamerInfoROOTFile;
   config.fAddStreamerInfoToROOTFile = &AddStreamerInfoToROOTFile;
   config.fAddTypedefToROOTFile = &AddTypedefToROOTFile;
   config.fAddEnumToROOTFile = &AddEnumToROOTFile;
   config.fAddAncestorPCMROOTFile = &AddAncestorPCMROOTFile;
   config.fCloseStreamerInfoROOTFile = &CloseStreamerInfoROOTFile;
#endif
   return ROOT_rootcling_Driver(argc, argv, config);
}
<commit_msg>Leave only stage 1 part of rootcling.cxx<commit_after>// Authors: Axel Naumann, Philippe Canal, Danilo Piparo

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "rootcling_impl.h"
#include "RConfigure.h"
#include "RConfig.h"

#include <iostream>

#ifdef _WIN32
# ifdef system
#  undef system
# endif
# include <windows.h>
# include <Tlhelp32.h> // for MAX_MODULE_NAME32
# include <process.h>
# define PATH_MAX _MAX_PATH
# ifdef interface
// prevent error coming from clang/AST/Attrs.inc
#  undef interface
# endif
#else // _WIN32
# include <limits.h>
# include <unistd.h>
# include <dlfcn.h>
#endif

#ifdef __APPLE__
#include <libgen.h> // Needed for basename
#include <mach-o/dyld.h>
#endif

extern "C" {
R__DLLEXPORT void usedToIdentifyRootClingByDlSym() {}
}

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

#ifdef __ICC
#pragma warning disable 69
#endif

ROOT::Internal::RootCling::TROOTSYSSetter gROOTSYSSetter;

int main(int argc, char **argv)
{
   // Force the emission of the symbol - the compiler cannot know that argv
   // is always set.
   if (!argv) {
      auto dummyVal =  (int)(long)&usedToIdentifyRootClingByDlSym;
      return dummyVal;
   }

   ROOT::Internal::RootCling::DriverConfig config{};
#ifdef R__HAVE_LLVMRESOURCEDIR
  config.fLLVMResourceDir= "@R__LLVMRESOURCEDIR@";
#endif

   config.fBuildingROOTStage1 = true;

   return ROOT_rootcling_Driver(argc, argv, config);
}
<|endoftext|>


<commit_before>// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/// @file   AliHLTTPCHWCFData.cxx
/// @author Matthias Richter
/// @date   2011-08-04
/// @brief  Decoder methods for the HWCF format
///
#include "AliHLTTPCHWCFData.h"
#include "AliHLTErrorGuard.h"
#include "AliHLTTPCHWCFEmulator.h"
#include "AliHLTTPCTransform.h"
#include "AliRawDataHeader.h"
#include "TFile.h"
#include <memory>
#include <ostream>

ClassImp(AliHLTTPCHWCFData) //ROOT macro for the implementation of ROOT specific class methods

AliHLTTPCHWCFData::AliHLTTPCHWCFData(int forceVersion)
 : fpBuffer(NULL)
 , fBufferSize(0)
 , fVersion(-1)
 , fForcedVersion(forceVersion)
 , fRCUTrailerSize(0)
 , fpFileBuffer(NULL)
 , fIterator()
 , fIteratorEnd()
{
  // constructor
}

const unsigned AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize=sizeof(AliHLTTPCHWCFData::AliHLTTPCHWClusterV1)/sizeof(AliHLTUInt32_t);

AliHLTTPCHWCFData::~AliHLTTPCHWCFData()
{
  // destructor
  if (fpFileBuffer) delete fpFileBuffer;
}

int AliHLTTPCHWCFData::Init(const AliHLTUInt8_t* pBuffer, int bufferSize)
{
  // init the internal pointer
  Reset();
  if (!pBuffer || (unsigned)bufferSize<sizeof(AliHLTUInt32_t)) return -EINVAL;
  if (bufferSize%sizeof(AliHLTUInt32_t)) {
    HLTError("invalid buffer size %d, expecting multiple of 4", bufferSize);
    return -EINVAL;
  }
  const AliHLTUInt32_t* rcuTrailer=reinterpret_cast<const AliHLTUInt32_t*>(pBuffer);
  rcuTrailer+=bufferSize/sizeof(AliHLTUInt32_t)-1;

  if ((*rcuTrailer >> 30) != 3) {
    // The HWCFEmulator does not write the RCU trailer at the moment
    // skip this error
    // HLTError("can not read last rcu trailer word");
    // return -ENODATA;
  } else {
    // number of 32 bit RCU trailer words can be found in the last word
    int nofRCUTrailerWords = (*rcuTrailer & 0x7F);
    if (nofRCUTrailerWords < 2) {
      HLTError("Invalid trailer size found (%d bytes)", nofRCUTrailerWords*4);
      return -ENODATA;
    }

    if (nofRCUTrailerWords*4>bufferSize) {
      HLTError("inconsistent RCU trailer size, exceeds buffer size");
      return -ENODATA;
    }

    // check if the first RCU trailer word starts with pattern '10'
    rcuTrailer-=nofRCUTrailerWords-1;
    if ((*rcuTrailer >> 30) != 2) {
      HLTError("inconsistent RCU trailer word: can not find indicator patter '10' in bit 30 and 31 (0x08x)", *rcuTrailer);
      return -ENODATA;
    }

    fRCUTrailerSize = nofRCUTrailerWords*4;
  }

  fpBuffer=pBuffer;
  fBufferSize=bufferSize;

  return 0;
}

int AliHLTTPCHWCFData::Reset()
{
  // reset
  fpBuffer=NULL;
  fBufferSize=0;
  fRCUTrailerSize=0;
  return 0;
}

int AliHLTTPCHWCFData::CheckVersion()
{
  // check the data buffer for format version
  if (fVersion>=0) return fVersion;
  if (CheckAssumption(kHWCFDataV1, fpBuffer, fBufferSize-fRCUTrailerSize)) {
    fVersion=kHWCFDataV1;
  } else if (CheckAssumption(kHWCFDataV0, fpBuffer, fBufferSize-fRCUTrailerSize)) {
    fVersion=kHWCFDataV0;
  }
  return fVersion;
}

bool AliHLTTPCHWCFData::CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const
{
  // check the format assumption for data buffer
  int elementsize=GetElementSize(format);
  // size has to be known
  if (elementsize<0) return false;
  // buffer must be multiple of element size
  if (size<elementsize || (size%elementsize)!=0) return false;
  for (int trial=0; trial<10 && (trial+1)*elementsize<=size; trial++) {
    AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(*reinterpret_cast<const AliHLTUInt32_t*>(pData+trial*elementsize));
    // cluster header starts with 11 in bit 30 and 31
    if ((header&0xc0000000)!=0xc0000000) return false;
    // check that the padrow is within bounds
    if (((header >> 24) & 0x3f)>(unsigned)AliHLTTPCTransform::GetNRows(-1)) return false;
  }
  return true;
}

Int_t AliHLTTPCHWCFData::GetNumberOfClusters() const
{
  // get number of clusters
  if (fVersion<0) return 0;
  int elementsize=GetElementSize(fVersion);
  if (elementsize<0) return 0;
  if (!fpBuffer || fBufferSize==0 || fBufferSize<fRCUTrailerSize) return 0;
  return (fBufferSize-fRCUTrailerSize)/elementsize;
}

Int_t    AliHLTTPCHWCFData::GetPadRow(int i)  const
{
  // get raw coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPadRow();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPadRow();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

Float_t  AliHLTTPCHWCFData::GetPad(int i)     const
{
  // get pad coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPad();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPad();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetTime(int i)    const
{
  // get time coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetTime();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetTime();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetSigmaY2(int i) const
{
  // get sigmaY2 coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaY2();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaY2();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetSigmaZ2(int i) const
{
  // get sigmaZ2 coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaZ2();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaZ2();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Int_t    AliHLTTPCHWCFData::GetCharge(int i)  const
{
  // get charge coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetCharge();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetCharge();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

Int_t    AliHLTTPCHWCFData::GetQMax(int i)    const
{
  // get qmax coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetQMax();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetQMax();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

void AliHLTTPCHWCFData::Print(const char* option)
{
  // print info
  cout << "HWCF format version " << fVersion << endl;
  if (fVersion<0) return;

  cout << "    " << GetNumberOfClusters() << " cluster(s)" << endl;
  if (GetRCUTrailerSize()>0) {
    cout << "    RCU trailer: " << GetRCUTrailerSize() << " word(s)" << endl;
  }

  if (strcmp(option, "all")==0) {
    for (unsigned i=0; (int)i<GetNumberOfClusters(); i++) {
      cout << /* setw(5) <<*/ i << ":";
      cout << /* setw(8) <<*/ " " << GetPadRow(i);
      cout << /* setw(8) <<*/ " " << GetPad(i);
      cout << /* setw(8) <<*/ " " << GetTime(i);
      cout << /* setw(8) <<*/ " " << GetSigmaY2(i);
      cout << /* setw(8) <<*/ " " << GetSigmaZ2(i);
      cout << /* setw(8) <<*/ " " << GetCharge(i);
      cout << /* setw(8) <<*/ " " << GetQMax(i);
      cout << endl;
    }
  }
}

int AliHLTTPCHWCFData::Open(const char* filename)
{
  // open block from file and add to collection
  if (!filename) return -EINVAL;

  TString input=filename;
  input+="?filetype=raw";
  std::auto_ptr<TFile> pFile(new TFile(input));
  if (!pFile.get()) return -ENOMEM;
  if (pFile->IsZombie()) return -ENOENT;

  int iResult=0;
  if (pFile->GetSize()<(int)sizeof(AliRawDataHeader)) {
    HLTError("file %s to small", filename);
    return -ENODATA;
  }

  pFile->Seek(0);
  std::auto_ptr<TArrayC> buffer(new TArrayC);
  if (!buffer.get()) return -ENOMEM;

  buffer->Set(pFile->GetSize());
  if (pFile->ReadBuffer(buffer->GetArray(), buffer->GetSize())==0) {
  } else {
    HLTError("failed reading %d byte(s) from file %s", pFile->GetSize(), filename);
    iResult=-ENODATA;
  }

  AliHLTUInt8_t* pBuffer=reinterpret_cast<AliHLTUInt8_t*>(buffer->GetArray()+sizeof(AliRawDataHeader));
  unsigned bufferSize=buffer->GetSize()-sizeof(AliRawDataHeader);
  if ((iResult=Init(pBuffer, bufferSize))<0 ||
      (iResult=CheckVersion())<0) {
    Reset();
    return iResult;
  }

  fpFileBuffer=buffer.release();
  return GetNumberOfClusters();
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetPadRow()  const
{
  // bit 24 to 29
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  if ((header>>30) != 3) return -EBADMSG;
  return (header >> 24) & 0x3f;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetCharge()  const
{
  // 24 bit fixed point number with 6 bits after the point
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  return (header & 0xFFFFFF )>>6;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetPadRow()  const
{
  // bit 24 to 29
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  if ((header>>30) != 3) return -EBADMSG;
  return (header >> 24) & 0x3f;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetCharge()  const
{
  // 32 bit fixed point number with 12 bits after the point
  return AliHLTTPCHWCFEmulator::ReadBigEndian(fCharge)>>12;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetQMax()    const
{
  // 24 bit fixed point number with 12 bits after the point
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  return (header & 0xFFFFFF )>>12;
}
<commit_msg>correcting a typo in the error message for invalid RCU trailer and including some more information<commit_after>// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/// @file   AliHLTTPCHWCFData.cxx
/// @author Matthias Richter
/// @date   2011-08-04
/// @brief  Decoder methods for the HWCF format
///
#include "AliHLTTPCHWCFData.h"
#include "AliHLTErrorGuard.h"
#include "AliHLTTPCHWCFEmulator.h"
#include "AliHLTTPCTransform.h"
#include "AliRawDataHeader.h"
#include "TFile.h"
#include <memory>
#include <ostream>

ClassImp(AliHLTTPCHWCFData) //ROOT macro for the implementation of ROOT specific class methods

AliHLTTPCHWCFData::AliHLTTPCHWCFData(int forceVersion)
 : fpBuffer(NULL)
 , fBufferSize(0)
 , fVersion(-1)
 , fForcedVersion(forceVersion)
 , fRCUTrailerSize(0)
 , fpFileBuffer(NULL)
 , fIterator()
 , fIteratorEnd()
{
  // constructor
}

const unsigned AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize=sizeof(AliHLTTPCHWCFData::AliHLTTPCHWClusterV1)/sizeof(AliHLTUInt32_t);

AliHLTTPCHWCFData::~AliHLTTPCHWCFData()
{
  // destructor
  if (fpFileBuffer) delete fpFileBuffer;
}

int AliHLTTPCHWCFData::Init(const AliHLTUInt8_t* pBuffer, int bufferSize)
{
  // init the internal pointer
  Reset();
  if (!pBuffer || (unsigned)bufferSize<sizeof(AliHLTUInt32_t)) return -EINVAL;
  if (bufferSize%sizeof(AliHLTUInt32_t)) {
    HLTError("invalid buffer size %d, expecting multiple of 4", bufferSize);
    return -EINVAL;
  }
  const AliHLTUInt32_t* rcuTrailer=reinterpret_cast<const AliHLTUInt32_t*>(pBuffer);
  rcuTrailer+=bufferSize/sizeof(AliHLTUInt32_t)-1;

  if ((*rcuTrailer >> 30) != 3) {
    // The HWCFEmulator does not write the RCU trailer at the moment
    // skip this error
    // HLTError("can not read last rcu trailer word");
    // return -ENODATA;
  } else {
    // number of 32 bit RCU trailer words can be found in the last word
    int nofRCUTrailerWords = (*rcuTrailer & 0x7F);
    if (nofRCUTrailerWords < 2) {
      HLTError("Invalid trailer size found (%d bytes)", nofRCUTrailerWords*4);
      return -ENODATA;
    }

    if (nofRCUTrailerWords*4>bufferSize) {
      HLTError("inconsistent RCU trailer size, exceeds buffer size");
      return -ENODATA;
    }

    // check if the first RCU trailer word starts with pattern '10'
    rcuTrailer-=nofRCUTrailerWords-1;
    if ((*rcuTrailer >> 30) != 2) {
      HLTError("inconsistent first RCU trailer word: can not find indicator pattern '10' in bit 31 and 30 (0x%08x): trailer size %d word(s), buffer size %d byte", *rcuTrailer, nofRCUTrailerWords, bufferSize);
      return -ENODATA;
    }

    fRCUTrailerSize = nofRCUTrailerWords*4;
  }

  fpBuffer=pBuffer;
  fBufferSize=bufferSize;

  return 0;
}

int AliHLTTPCHWCFData::Reset()
{
  // reset
  fpBuffer=NULL;
  fBufferSize=0;
  fRCUTrailerSize=0;
  return 0;
}

int AliHLTTPCHWCFData::CheckVersion()
{
  // check the data buffer for format version
  if (fVersion>=0) return fVersion;
  if (CheckAssumption(kHWCFDataV1, fpBuffer, fBufferSize-fRCUTrailerSize)) {
    fVersion=kHWCFDataV1;
  } else if (CheckAssumption(kHWCFDataV0, fpBuffer, fBufferSize-fRCUTrailerSize)) {
    fVersion=kHWCFDataV0;
  }
  return fVersion;
}

bool AliHLTTPCHWCFData::CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const
{
  // check the format assumption for data buffer
  int elementsize=GetElementSize(format);
  // size has to be known
  if (elementsize<0) return false;
  // buffer must be multiple of element size
  if (size<elementsize || (size%elementsize)!=0) return false;
  for (int trial=0; trial<10 && (trial+1)*elementsize<=size; trial++) {
    AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(*reinterpret_cast<const AliHLTUInt32_t*>(pData+trial*elementsize));
    // cluster header starts with 11 in bit 30 and 31
    if ((header&0xc0000000)!=0xc0000000) return false;
    // check that the padrow is within bounds
    if (((header >> 24) & 0x3f)>(unsigned)AliHLTTPCTransform::GetNRows(-1)) return false;
  }
  return true;
}

Int_t AliHLTTPCHWCFData::GetNumberOfClusters() const
{
  // get number of clusters
  if (fVersion<0) return 0;
  int elementsize=GetElementSize(fVersion);
  if (elementsize<0) return 0;
  if (!fpBuffer || fBufferSize==0 || fBufferSize<fRCUTrailerSize) return 0;
  return (fBufferSize-fRCUTrailerSize)/elementsize;
}

Int_t    AliHLTTPCHWCFData::GetPadRow(int i)  const
{
  // get raw coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPadRow();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPadRow();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

Float_t  AliHLTTPCHWCFData::GetPad(int i)     const
{
  // get pad coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPad();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPad();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetTime(int i)    const
{
  // get time coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetTime();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetTime();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetSigmaY2(int i) const
{
  // get sigmaY2 coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaY2();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaY2();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Float_t  AliHLTTPCHWCFData::GetSigmaZ2(int i) const
{
  // get sigmaZ2 coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaZ2();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaZ2();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -10000.;
}

Int_t    AliHLTTPCHWCFData::GetCharge(int i)  const
{
  // get charge coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetCharge();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetCharge();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

Int_t    AliHLTTPCHWCFData::GetQMax(int i)    const
{
  // get qmax coordinate
  if (fVersion>=0 && CheckBounds(i)) {
    switch (fVersion) {
    case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetQMax();
    case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetQMax();
    default:
      ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
    }
  }
  return -1;
}

void AliHLTTPCHWCFData::Print(const char* option)
{
  // print info
  cout << "HWCF format version " << fVersion << endl;
  if (fVersion<0) return;

  cout << "    " << GetNumberOfClusters() << " cluster(s)" << endl;
  if (GetRCUTrailerSize()>0) {
    cout << "    RCU trailer: " << GetRCUTrailerSize() << " word(s)" << endl;
  }

  if (strcmp(option, "all")==0) {
    for (unsigned i=0; (int)i<GetNumberOfClusters(); i++) {
      cout << /* setw(5) <<*/ i << ":";
      cout << /* setw(8) <<*/ " " << GetPadRow(i);
      cout << /* setw(8) <<*/ " " << GetPad(i);
      cout << /* setw(8) <<*/ " " << GetTime(i);
      cout << /* setw(8) <<*/ " " << GetSigmaY2(i);
      cout << /* setw(8) <<*/ " " << GetSigmaZ2(i);
      cout << /* setw(8) <<*/ " " << GetCharge(i);
      cout << /* setw(8) <<*/ " " << GetQMax(i);
      cout << endl;
    }
  }
}

int AliHLTTPCHWCFData::Open(const char* filename)
{
  // open block from file and add to collection
  if (!filename) return -EINVAL;

  TString input=filename;
  input+="?filetype=raw";
  std::auto_ptr<TFile> pFile(new TFile(input));
  if (!pFile.get()) return -ENOMEM;
  if (pFile->IsZombie()) return -ENOENT;

  int iResult=0;
  if (pFile->GetSize()<(int)sizeof(AliRawDataHeader)) {
    HLTError("file %s to small", filename);
    return -ENODATA;
  }

  pFile->Seek(0);
  std::auto_ptr<TArrayC> buffer(new TArrayC);
  if (!buffer.get()) return -ENOMEM;

  buffer->Set(pFile->GetSize());
  if (pFile->ReadBuffer(buffer->GetArray(), buffer->GetSize())==0) {
  } else {
    HLTError("failed reading %d byte(s) from file %s", pFile->GetSize(), filename);
    iResult=-ENODATA;
  }

  AliHLTUInt8_t* pBuffer=reinterpret_cast<AliHLTUInt8_t*>(buffer->GetArray()+sizeof(AliRawDataHeader));
  unsigned bufferSize=buffer->GetSize()-sizeof(AliRawDataHeader);
  if ((iResult=Init(pBuffer, bufferSize))<0 ||
      (iResult=CheckVersion())<0) {
    Reset();
    return iResult;
  }

  fpFileBuffer=buffer.release();
  return GetNumberOfClusters();
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetPadRow()  const
{
  // bit 24 to 29
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  if ((header>>30) != 3) return -EBADMSG;
  return (header >> 24) & 0x3f;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetCharge()  const
{
  // 24 bit fixed point number with 6 bits after the point
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  return (header & 0xFFFFFF )>>6;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetPadRow()  const
{
  // bit 24 to 29
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  if ((header>>30) != 3) return -EBADMSG;
  return (header >> 24) & 0x3f;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetCharge()  const
{
  // 32 bit fixed point number with 12 bits after the point
  return AliHLTTPCHWCFEmulator::ReadBigEndian(fCharge)>>12;
}

Int_t    AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetQMax()    const
{
  // 24 bit fixed point number with 12 bits after the point
  AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
  return (header & 0xFFFFFF )>>12;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 Gunar Schorcht
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License v2.1. See the file LICENSE in the top level
 * directory for more details.
 */

/**
 * @ingroup     sys_arduino_api
 * @{
 *
 * @author      Gunar Schorcht <gunar@schorcht.net>
 * @file
 *
 * @brief       Definition of the Arduino 'Wire Library' for TwoWire interfaces
 * @}
 */

#if MODULE_PERIPH_I2C

extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
}

#include "Wire.h"

#include "log.h"
#include "panic.h"
#include "periph/i2c.h"

#define ENABLE_DEBUG 0
#include "debug.h"

#define WIRE_PORT_OK                    (0)
#define WIRE_PORT_ERROR_DATA_TO_LONG    (1)
#define WIRE_PORT_ERROR_ADDR_NACK       (2)
#define WIRE_PORT_ERROR_DATA_NACK       (3)
#define WIRE_PORT_ERROR_OTHER           (4)

/* Initialize Class Variables */

uint8_t TwoWire::rxBuffer[WIREPORT_BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;

uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[WIREPORT_BUFFER_LENGTH];
uint8_t TwoWire::txBufferIndex = 0;
uint8_t TwoWire::txBufferLength = 0;
uint8_t TwoWire::txError = 0;

uint8_t TwoWire::transmitting = 0;

/* Constructors */

TwoWire::TwoWire(void)
{
    DEBUG("[wire] %s\n", __func__);
}

/* Public Methods */

void TwoWire::begin(void)
{
    DEBUG("[wire] %s\n", __func__);

    rxBufferIndex = 0;
    rxBufferLength = 0;

    txBufferIndex = 0;
    txBufferLength = 0;

    i2c_init(ARDUINO_I2C_DEV);
}

void TwoWire::begin(uint8_t addr)
{
    (void)addr;
    DEBUG("[wire] %s\n", __func__);
    core_panic(PANIC_GENERAL_ERROR, "[wire] slave mode is not supported");
}

void TwoWire::setClock(uint32_t clk)
{
    (void)clk;
    /* not possible, bus speed is defined by the board definition */
    DEBUG("[wire] %s: clock is defined by board definition\n", __func__);
}

uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t size, uint8_t stop)
{
    DEBUG("[wire] %s: addr %02x, size %d, stop %d\n", __func__, addr, size, stop);

    if (size > WIREPORT_BUFFER_LENGTH) {
        size = WIREPORT_BUFFER_LENGTH;
    }

    uint8_t read = 0;

    if (i2c_acquire(ARDUINO_I2C_DEV) == 0) {
        if (i2c_read_bytes(ARDUINO_I2C_DEV, addr, rxBuffer, size,
                           stop ? 0 : I2C_NOSTOP) == 0) {
            read = size;
        }
        i2c_release(ARDUINO_I2C_DEV);
    }

    rxBufferIndex = 0;
    rxBufferLength = read;

    return read;
}

uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t size) {
    return requestFrom(addr, size, 1);
}

void TwoWire::beginTransmission(uint8_t addr)
{
    DEBUG("[wire] %s: addr %02x\n", __func__, addr);
    transmitting = 1;
    txAddress = addr;
    txBufferIndex = 0;
    txBufferLength = 0;
}

uint8_t TwoWire::endTransmission(uint8_t stop)
{
    DEBUG("[wire] %s: stop %d\n", __func__, stop);

    if (txError) {
        return txError;
    }

    if (i2c_acquire(ARDUINO_I2C_DEV) != 0) {
        return WIRE_PORT_ERROR_OTHER;
    }

    int res = i2c_write_bytes(ARDUINO_I2C_DEV,
                              txAddress, txBuffer, txBufferLength,
                              stop ? 0 : I2C_NOSTOP);
    switch (res) {
        case 0: break;
        case ENXIO: res = WIRE_PORT_ERROR_ADDR_NACK;
                    break;
        case EIO: res = WIRE_PORT_ERROR_DATA_NACK;
                  break;
        default: res = WIRE_PORT_ERROR_OTHER;
    }

    i2c_release(ARDUINO_I2C_DEV);

    txBufferIndex = 0;
    txBufferLength = 0;
    txError = 0;
    transmitting = 0;

    return res;
}

uint8_t TwoWire::endTransmission(void)
{
    return endTransmission(true);
}

size_t TwoWire::write(uint8_t data)
{
    DEBUG("[wire] %s: data %02x\n", __func__, data);

    if (!transmitting || txBufferLength >= WIREPORT_BUFFER_LENGTH) {
        txError = WIRE_PORT_ERROR_DATA_TO_LONG;
        return 0;
    }

    txBuffer[txBufferIndex++] = data;
    txBufferLength = txBufferIndex;

    return 1;
}

size_t TwoWire::write(const uint8_t *data, size_t size)
{
    DEBUG("[wire] %s: data %p, size %d\n", __func__, data, size);
    for (size_t i = 0; i < size; i++) {
        if (!write(data[i])) {
            return i;
        }
    }

    return size;
}

int TwoWire::available(void)
{
    DEBUG("[wire] %s: return %d\n", __func__, rxBufferLength - rxBufferIndex);
    return rxBufferLength - rxBufferIndex;
}

int TwoWire::read(void)
{
    DEBUG("[wire] %s\n", __func__);

    int value = -1;
    if (rxBufferIndex < rxBufferLength) {
        value = rxBuffer[rxBufferIndex];
        ++rxBufferIndex;
    }
    return value;
}

size_t TwoWire::readBytes(uint8_t *buffer, size_t length)
{
    DEBUG("[wire] %s\n", __func__);

    for (size_t i = 0; i < length; i++) {
        int byte = read();
        if (byte == -1) {
            return i;
        }
        buffer[i] = byte;
    }
    return length;
}

int TwoWire::peek(void)
{
    DEBUG("[wire] %s\n", __func__);

    int value = -1;
    if (rxBufferIndex < rxBufferLength) {
        value = rxBuffer[rxBufferIndex];
    }
    return value;
}

void TwoWire::flush(void)
{
    DEBUG("[wire] %s\n", __func__);

    rxBufferIndex = 0;
    rxBufferLength = 0;
    txBufferIndex = 0;
    txBufferLength = 0;
}

/* single instance */

TwoWire Wire;

#else /* MODULE_PERIPH_I2C */

typedef int dont_be_pedantic;

#endif /* MODULE_PERIPH_I2C */
<commit_msg>sys/arduino: update TwoWire class to new I2C API<commit_after>/*
 * Copyright (C) 2018 Gunar Schorcht
 *
 * This file is subject to the terms and conditions of the GNU Lesser
 * General Public License v2.1. See the file LICENSE in the top level
 * directory for more details.
 */

/**
 * @ingroup     sys_arduino_api
 * @{
 *
 * @author      Gunar Schorcht <gunar@schorcht.net>
 * @file
 *
 * @brief       Definition of the Arduino 'Wire Library' for TwoWire interfaces
 * @}
 */

#if MODULE_PERIPH_I2C

extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
}

#include "Wire.h"

#include "log.h"
#include "panic.h"
#include "periph/i2c.h"

#define ENABLE_DEBUG 0
#include "debug.h"

#define WIRE_PORT_OK                    (0)
#define WIRE_PORT_ERROR_DATA_TO_LONG    (1)
#define WIRE_PORT_ERROR_ADDR_NACK       (2)
#define WIRE_PORT_ERROR_DATA_NACK       (3)
#define WIRE_PORT_ERROR_OTHER           (4)

/* Initialize Class Variables */

uint8_t TwoWire::rxBuffer[WIREPORT_BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;

uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[WIREPORT_BUFFER_LENGTH];
uint8_t TwoWire::txBufferIndex = 0;
uint8_t TwoWire::txBufferLength = 0;
uint8_t TwoWire::txError = 0;

uint8_t TwoWire::transmitting = 0;

/* Constructors */

TwoWire::TwoWire(void)
{
    DEBUG("[wire] %s\n", __func__);
}

/* Public Methods */

void TwoWire::begin(void)
{
    DEBUG("[wire] %s\n", __func__);

    rxBufferIndex = 0;
    rxBufferLength = 0;

    txBufferIndex = 0;
    txBufferLength = 0;

    i2c_init(ARDUINO_I2C_DEV);
}

void TwoWire::begin(uint8_t addr)
{
    (void)addr;
    DEBUG("[wire] %s\n", __func__);
    core_panic(PANIC_GENERAL_ERROR, "[wire] slave mode is not supported");
}

void TwoWire::setClock(uint32_t clk)
{
    (void)clk;
    /* not possible, bus speed is defined by the board definition */
    DEBUG("[wire] %s: clock is defined by board definition\n", __func__);
}

uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t size, uint8_t stop)
{
    DEBUG("[wire] %s: addr %02x, size %d, stop %d\n", __func__, addr, size, stop);

    if (size > WIREPORT_BUFFER_LENGTH) {
        size = WIREPORT_BUFFER_LENGTH;
    }

    uint8_t read = 0;

    i2c_acquire(ARDUINO_I2C_DEV);
    if (i2c_read_bytes(ARDUINO_I2C_DEV, addr, rxBuffer, size,
                       stop ? 0 : I2C_NOSTOP) == 0) {
        read = size;
    }
    i2c_release(ARDUINO_I2C_DEV);

    rxBufferIndex = 0;
    rxBufferLength = read;

    return read;
}

uint8_t TwoWire::requestFrom(uint8_t addr, uint8_t size) {
    return requestFrom(addr, size, 1);
}

void TwoWire::beginTransmission(uint8_t addr)
{
    DEBUG("[wire] %s: addr %02x\n", __func__, addr);
    transmitting = 1;
    txAddress = addr;
    txBufferIndex = 0;
    txBufferLength = 0;
}

uint8_t TwoWire::endTransmission(uint8_t stop)
{
    DEBUG("[wire] %s: stop %d\n", __func__, stop);

    if (txError) {
        return txError;
    }

    i2c_acquire(ARDUINO_I2C_DEV);

    int res = i2c_write_bytes(ARDUINO_I2C_DEV,
                              txAddress, txBuffer, txBufferLength,
                              stop ? 0 : I2C_NOSTOP);
    switch (res) {
        case 0: break;
        case ENXIO: res = WIRE_PORT_ERROR_ADDR_NACK;
                    break;
        case EIO: res = WIRE_PORT_ERROR_DATA_NACK;
                  break;
        default: res = WIRE_PORT_ERROR_OTHER;
    }

    i2c_release(ARDUINO_I2C_DEV);

    txBufferIndex = 0;
    txBufferLength = 0;
    txError = 0;
    transmitting = 0;

    return res;
}

uint8_t TwoWire::endTransmission(void)
{
    return endTransmission(true);
}

size_t TwoWire::write(uint8_t data)
{
    DEBUG("[wire] %s: data %02x\n", __func__, data);

    if (!transmitting || txBufferLength >= WIREPORT_BUFFER_LENGTH) {
        txError = WIRE_PORT_ERROR_DATA_TO_LONG;
        return 0;
    }

    txBuffer[txBufferIndex++] = data;
    txBufferLength = txBufferIndex;

    return 1;
}

size_t TwoWire::write(const uint8_t *data, size_t size)
{
    DEBUG("[wire] %s: data %p, size %d\n", __func__, data, size);
    for (size_t i = 0; i < size; i++) {
        if (!write(data[i])) {
            return i;
        }
    }

    return size;
}

int TwoWire::available(void)
{
    DEBUG("[wire] %s: return %d\n", __func__, rxBufferLength - rxBufferIndex);
    return rxBufferLength - rxBufferIndex;
}

int TwoWire::read(void)
{
    DEBUG("[wire] %s\n", __func__);

    int value = -1;
    if (rxBufferIndex < rxBufferLength) {
        value = rxBuffer[rxBufferIndex];
        ++rxBufferIndex;
    }
    return value;
}

size_t TwoWire::readBytes(uint8_t *buffer, size_t length)
{
    DEBUG("[wire] %s\n", __func__);

    for (size_t i = 0; i < length; i++) {
        int byte = read();
        if (byte == -1) {
            return i;
        }
        buffer[i] = byte;
    }
    return length;
}

int TwoWire::peek(void)
{
    DEBUG("[wire] %s\n", __func__);

    int value = -1;
    if (rxBufferIndex < rxBufferLength) {
        value = rxBuffer[rxBufferIndex];
    }
    return value;
}

void TwoWire::flush(void)
{
    DEBUG("[wire] %s\n", __func__);

    rxBufferIndex = 0;
    rxBufferLength = 0;
    txBufferIndex = 0;
    txBufferLength = 0;
}

/* single instance */

TwoWire Wire;

#else /* MODULE_PERIPH_I2C */

typedef int dont_be_pedantic;

#endif /* MODULE_PERIPH_I2C */
<|endoftext|>


<commit_before>/*
 * Kurento Android Media: Android Media Library based on FFmpeg.
 * Copyright (C) 2011  Tikal Technologies
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

extern "C" {
#include <jni.h>

#include <util/log.h>
#include <init-log.h>
}

#include "MediaPortManager.h"
#include <AudioRx.h>
#include <VideoRx.h>

using namespace media;

static char* LOG_TAG = "NDK-media-rx";
static AudioRx *aRxObj;
static VideoRx *vRxObj;

extern "C" {
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_startVideoRx(JNIEnv* env, jclass clazz,
				jlong videoMediaPortRef, jstring sdp, jint maxDelay, jobject videoReceiver);
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_stopVideoRx(JNIEnv* env, jclass clazz);

	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_startAudioRx(JNIEnv* env, jclass clazz,
				jlong audioMediaPortRef, jstring sdp, jint maxDelay, jobject audioReceiver);
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_stopAudioRx(JNIEnv* env, jclass clazz);
}

static jobject video_receiver;
static jclass VideoFrame_class;
static jmethodID put_video_frame_rx_mid, get_frame_buffer_mid, VideoFrame_init_mid;
static JNIEnv* video_env;

enum {
	ANDROID_PIX_FMT = PIX_FMT_RGB32,
};

static DecodedFrame df;

static int current_width, current_height;

static jobject
create_videoframe_obj(JNIEnv *env, DecodedFrame *df)
{
	return env->NewObject(VideoFrame_class, VideoFrame_init_mid,
				(jintArray)df->priv_data, df->width, df->height,
				df->time_base.num, df->time_base.den,
				df->pts, df->start_time, df->rx_time,
				df->encoded_size);
}

static void
android_put_video_frame_rx(DecodedFrame *decoded_frame)
{
	jobject df_obj;

	df_obj = create_videoframe_obj(video_env, decoded_frame);
	if (df_obj)
		video_env->CallVoidMethod(video_receiver,
						put_video_frame_rx_mid, df_obj);
	video_env->DeleteLocalRef(df_obj);
}

static DecodedFrame*
android_get_decoded_frame(int width, int height)
{
	int picture_nbytes;

	// Determine required picture size
	picture_nbytes = avpicture_get_size((enum PixelFormat)ANDROID_PIX_FMT, width, height);

	video_env->DeleteLocalRef((jintArray)df.priv_data);
	df.priv_data = (jintArray)video_env->CallObjectMethod(video_receiver,
					get_frame_buffer_mid, picture_nbytes);
	if (!df.priv_data)
		return NULL;

	df.buffer = (uint8_t*)video_env->GetIntArrayElements((jintArray)df.priv_data, JNI_FALSE);
	video_env->ReleaseIntArrayElements((jintArray)df.priv_data, (jint*)(df.buffer), 0);
	avpicture_fill((AVPicture*) df.pFrameRGB, df.buffer,
				(enum PixelFormat)ANDROID_PIX_FMT, width, height);

	return &df;
}

static void
android_release_decoded_frame(void)
{
	video_env->DeleteLocalRef((jintArray)df.priv_data);
	av_free(df.pFrameRGB);
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_startVideoRx(JNIEnv* env, jclass clazz,
				jlong videoMediaPortRef, jstring sdp, jint maxDelay,
				jobject videoReceiver)
{
	int ret;
	const char *p_sdp = NULL;
	MediaPort *videoMediaPort;

	jclass cls = NULL;

	current_width = 0;
	current_height = 0;

	put_video_frame_rx_mid = NULL;
	get_frame_buffer_mid = NULL;
	VideoFrame_init_mid = NULL;
	video_receiver = NULL;
	VideoFrame_class = NULL;

	if (init_log() != 0)
		media_log(MEDIA_LOG_WARN, LOG_TAG, "Couldn't init android log");

	p_sdp = env->GetStringUTFChars(sdp, NULL);
	if (p_sdp == NULL) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "OutOfMemoryError");
		return -1;
	}

	cls = env->GetObjectClass(videoReceiver);
	put_video_frame_rx_mid = env->GetMethodID(cls, "putVideoFrameRx",
				"(Lcom/kurento/kas/media/rx/VideoFrame;)V");
	if (!put_video_frame_rx_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
		"putVideoFrameRx(Lcom/kurento/kas/media/rx/VideoFrame;)V no exist");
		ret = -2;
		goto end;
	}

	get_frame_buffer_mid = env->GetMethodID(cls, "getFrameBuffer", "(I)[I");
	if (!get_frame_buffer_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "getFrameBuffer(I)[I no exist");
		ret = -3;
		goto end;
	}

	VideoFrame_class = env->FindClass("com/kurento/kas/media/rx/VideoFrame");
	if (!VideoFrame_class) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
				"com/kurento/kas/media/rx/VideoFrame not found");
		ret = -4;
		goto end;
	}

	VideoFrame_init_mid = env->GetMethodID(VideoFrame_class,
							"<init>", "([IIIIIJJJI)V");
	if (!VideoFrame_init_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "init([IIIIIJJJI)V not found");
		ret = -5;
		goto end;
	}

	video_env = env;
	video_receiver = videoReceiver;

	//Allocate AVFrame structure
	df.width = 0;
	df.height = 0;
	df.priv_data = NULL;
	df.pFrameRGB = avcodec_alloc_frame();
	if (df.pFrameRGB == NULL) {
		ret = -6;
		goto end;
	}

	FrameManager android_frame_manager;
	android_frame_manager.pix_fmt = (enum PixelFormat)ANDROID_PIX_FMT;
	android_frame_manager.put_video_frame_rx = android_put_video_frame_rx;
	android_frame_manager.get_decoded_frame = android_get_decoded_frame;
	android_frame_manager.release_decoded_frame =android_release_decoded_frame ;

	videoMediaPort = (MediaPort*)videoMediaPortRef;

	vRxObj = new VideoRx(videoMediaPort, p_sdp, maxDelay, &android_frame_manager);
	vRxObj->start();
	ret = 0;

end:
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(VideoFrame_class);
	env->ReleaseStringUTFChars(sdp, p_sdp);

	return ret;
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_stopVideoRx(JNIEnv* env, jclass clazz)
{
	if (vRxObj) {
		vRxObj->stop();
		delete vRxObj;
		vRxObj = NULL;
	}
	return 0;
}

static jobject audio_receiver;
static jclass AudioSamples_class;
static jmethodID audio_mid, AudioSamples_init_mid;
static JNIEnv* audio_env;

static jobject
create_audiosamples_obj(JNIEnv *env, DecodedAudioSamples *das)
{
	jobject das_obj = NULL;
	jbyteArray jbuf = NULL;

	jbuf = (jbyteArray)env->NewByteArray(das->size);
	env->SetByteArrayRegion(jbuf, 0, das->size, (jbyte*)das->samples);
	das_obj = env->NewObject(AudioSamples_class, AudioSamples_init_mid,
				jbuf, das->size,
				das->time_base.num, das->time_base.den,
				das->pts, das->start_time, das->rx_time,
				das->encoded_size);
	env->DeleteLocalRef(jbuf);

	return das_obj;
}

static void
android_put_audio_samples_rx(DecodedAudioSamples* decoded_audio_samples)
{
	jobject das_obj;

	das_obj = create_audiosamples_obj(audio_env, decoded_audio_samples);
	if (das_obj)
		audio_env->CallVoidMethod(audio_receiver,
							audio_mid, das_obj);
	audio_env->DeleteLocalRef(das_obj);
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_startAudioRx(JNIEnv* env, jclass clazz,
				jlong audioMediaPortRef, jstring sdp, jint maxDelay,
				jobject audioReceiver)
{
	int ret = 0;
	const char *p_sdp = NULL;
	MediaPort *audioMediaPort;

	jclass cls = NULL;

	audio_mid = NULL;
	AudioSamples_init_mid = NULL;
	audio_receiver = NULL;
	AudioSamples_class = NULL;

	if (init_log() != 0)
		media_log(MEDIA_LOG_WARN, LOG_TAG, "Couldn't init android log");

	p_sdp = env->GetStringUTFChars(sdp, NULL);
	if (p_sdp == NULL) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "OutOfMemoryError");
		return -1;
	}

	cls = env->GetObjectClass(audioReceiver);

	audio_mid = env->GetMethodID(cls, "putAudioSamplesRx",
				"(Lcom/kurento/kas/media/rx/AudioSamples;)V");
	if (audio_mid == 0) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
			"(Lcom/kurento/kas/media/rx/AudioSamples;)V no exists");
		ret = -2;
		goto end;
	}

	AudioSamples_class = env->FindClass("com/kurento/kas/media/rx/AudioSamples");
	if (!AudioSamples_class) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
				"com/kurento/kas/media/rx/AudioSamples not found");
		ret = -3;
		goto end;
	}

	AudioSamples_init_mid = env->GetMethodID(AudioSamples_class,
							"<init>", "([BIIIJJJI)V");
	if (!AudioSamples_init_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "init([BIIIJJJI)V not found");
		ret = -4;
		goto end;
	}

	audio_env = env;
	audio_receiver = audioReceiver;
	audioMediaPort = (MediaPort*)audioMediaPortRef;

	aRxObj = new AudioRx(audioMediaPort, p_sdp, maxDelay, &android_put_audio_samples_rx);
	aRxObj->start();

end:
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(audio_receiver);
	env->DeleteLocalRef(AudioSamples_class);
	env->ReleaseStringUTFChars(sdp, p_sdp);

	return ret;
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_stopAudioRx(JNIEnv* env, jclass clazz)
{
	if (aRxObj) {
		aRxObj->stop();
		delete aRxObj;
		aRxObj = NULL;
	}
	return 0;
}
<commit_msg>Use AudioRx and VideoRx classes.<commit_after>/*
 * Kurento Android Media: Android Media Library based on FFmpeg.
 * Copyright (C) 2011  Tikal Technologies
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

extern "C" {
#include <jni.h>

#include <util/log.h>
#include <init-log.h>
}

#include "MediaPortManager.h"
#include <AudioRx.h>
#include <VideoRx.h>

using namespace media;

static char* LOG_TAG = "NDK-media-rx";
static AudioRx *aRxObj;
static VideoRx *vRxObj;

extern "C" {
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_startVideoRx(JNIEnv* env, jclass clazz,
				jlong videoMediaPortRef, jstring sdp, jint maxDelay, jobject videoReceiver);
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_stopVideoRx(JNIEnv* env, jclass clazz);

	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_startAudioRx(JNIEnv* env, jclass clazz,
				jlong audioMediaPortRef, jstring sdp, jint maxDelay, jobject audioReceiver);
	JNIEXPORT jint JNICALL Java_com_kurento_kas_media_rx_MediaRx_stopAudioRx(JNIEnv* env, jclass clazz);
}

static jobject video_receiver;
static jclass VideoFrame_class;
static jmethodID put_video_frame_rx_mid, get_frame_buffer_mid, VideoFrame_init_mid;
static JNIEnv* video_env;

enum {
	ANDROID_PIX_FMT = PIX_FMT_RGB32,
};

static DecodedFrame df;

static int current_width, current_height;

static jobject
create_videoframe_obj(JNIEnv *env, DecodedFrame *df)
{
	return env->NewObject(VideoFrame_class, VideoFrame_init_mid,
				(jintArray)df->priv_data, df->width, df->height,
				df->time_base.num, df->time_base.den,
				df->pts, df->start_time, df->rx_time,
				df->encoded_size);
}

static void
android_put_video_frame_rx(DecodedFrame *decoded_frame)
{
	jobject df_obj;

	df_obj = create_videoframe_obj(video_env, decoded_frame);
	if (df_obj)
		video_env->CallVoidMethod(video_receiver,
						put_video_frame_rx_mid, df_obj);
	video_env->DeleteLocalRef(df_obj);
}

static DecodedFrame*
android_get_decoded_frame(int width, int height)
{
	int picture_nbytes;

	// Determine required picture size
	picture_nbytes = avpicture_get_size((enum PixelFormat)ANDROID_PIX_FMT, width, height);

	video_env->DeleteLocalRef((jintArray)df.priv_data);
	df.priv_data = (jintArray)video_env->CallObjectMethod(video_receiver,
					get_frame_buffer_mid, picture_nbytes);
	if (!df.priv_data)
		return NULL;

	df.buffer = (uint8_t*)video_env->GetIntArrayElements((jintArray)df.priv_data, JNI_FALSE);
	video_env->ReleaseIntArrayElements((jintArray)df.priv_data, (jint*)(df.buffer), 0);
	avpicture_fill((AVPicture*) df.pFrameRGB, df.buffer,
				(enum PixelFormat)ANDROID_PIX_FMT, width, height);

	return &df;
}

static void
android_release_decoded_frame(void)
{
	video_env->DeleteLocalRef((jintArray)df.priv_data);
	av_free(df.pFrameRGB);
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_startVideoRx(JNIEnv* env, jclass clazz,
				jlong videoMediaPortRef, jstring sdp, jint maxDelay,
				jobject videoReceiver)
{
	int ret;
	const char *p_sdp = NULL;
	MediaPort *videoMediaPort;

	jclass cls = NULL;

	current_width = 0;
	current_height = 0;

	put_video_frame_rx_mid = NULL;
	get_frame_buffer_mid = NULL;
	VideoFrame_init_mid = NULL;
	video_receiver = NULL;
	VideoFrame_class = NULL;

	if (init_log() != 0)
		media_log(MEDIA_LOG_WARN, LOG_TAG, "Couldn't init android log");

	p_sdp = env->GetStringUTFChars(sdp, NULL);
	if (p_sdp == NULL) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "OutOfMemoryError");
		return -1;
	}

	cls = env->GetObjectClass(videoReceiver);
	put_video_frame_rx_mid = env->GetMethodID(cls, "putVideoFrameRx",
				"(Lcom/kurento/kas/media/rx/VideoFrame;)V");
	if (!put_video_frame_rx_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
		"putVideoFrameRx(Lcom/kurento/kas/media/rx/VideoFrame;)V no exist");
		ret = -2;
		goto end;
	}

	get_frame_buffer_mid = env->GetMethodID(cls, "getFrameBuffer", "(I)[I");
	if (!get_frame_buffer_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "getFrameBuffer(I)[I no exist");
		ret = -3;
		goto end;
	}

	VideoFrame_class = env->FindClass("com/kurento/kas/media/rx/VideoFrame");
	if (!VideoFrame_class) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
				"com/kurento/kas/media/rx/VideoFrame not found");
		ret = -4;
		goto end;
	}

	VideoFrame_init_mid = env->GetMethodID(VideoFrame_class,
							"<init>", "([IIIIIJJJI)V");
	if (!VideoFrame_init_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "init([IIIIIJJJI)V not found");
		ret = -5;
		goto end;
	}

	video_env = env;
	video_receiver = videoReceiver;

	//Allocate AVFrame structure
	df.width = 0;
	df.height = 0;
	df.priv_data = NULL;
	df.pFrameRGB = avcodec_alloc_frame();
	if (df.pFrameRGB == NULL) {
		ret = -6;
		goto end;
	}

	FrameManager android_frame_manager;
	android_frame_manager.pix_fmt = (enum PixelFormat)ANDROID_PIX_FMT;
	android_frame_manager.put_video_frame_rx = android_put_video_frame_rx;
	android_frame_manager.get_decoded_frame = android_get_decoded_frame;
	android_frame_manager.release_decoded_frame =android_release_decoded_frame ;

	videoMediaPort = (MediaPort*)videoMediaPortRef;

	try {
		vRxObj = new VideoRx(videoMediaPort, p_sdp, maxDelay, &android_frame_manager);
		vRxObj->start();
	}
	catch(MediaException &e) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "exception: %s", e.what());
	}

	ret = 0;

end:
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(VideoFrame_class);
	env->ReleaseStringUTFChars(sdp, p_sdp);

	return ret;
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_stopVideoRx(JNIEnv* env, jclass clazz)
{
	if (vRxObj) {
		vRxObj->stop();
		delete vRxObj;
		vRxObj = NULL;
	}
	return 0;
}

static jobject audio_receiver;
static jclass AudioSamples_class;
static jmethodID audio_mid, AudioSamples_init_mid;
static JNIEnv* audio_env;

static jobject
create_audiosamples_obj(JNIEnv *env, DecodedAudioSamples *das)
{
	jobject das_obj = NULL;
	jbyteArray jbuf = NULL;

	jbuf = (jbyteArray)env->NewByteArray(das->size);
	env->SetByteArrayRegion(jbuf, 0, das->size, (jbyte*)das->samples);
	das_obj = env->NewObject(AudioSamples_class, AudioSamples_init_mid,
				jbuf, das->size,
				das->time_base.num, das->time_base.den,
				das->pts, das->start_time, das->rx_time,
				das->encoded_size);
	env->DeleteLocalRef(jbuf);

	return das_obj;
}

static void
android_put_audio_samples_rx(DecodedAudioSamples* decoded_audio_samples)
{
	jobject das_obj;

	das_obj = create_audiosamples_obj(audio_env, decoded_audio_samples);
	if (das_obj)
		audio_env->CallVoidMethod(audio_receiver,
							audio_mid, das_obj);
	audio_env->DeleteLocalRef(das_obj);
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_startAudioRx(JNIEnv* env, jclass clazz,
				jlong audioMediaPortRef, jstring sdp, jint maxDelay,
				jobject audioReceiver)
{
	int ret = 0;
	const char *p_sdp = NULL;
	MediaPort *audioMediaPort;

	jclass cls = NULL;

	audio_mid = NULL;
	AudioSamples_init_mid = NULL;
	audio_receiver = NULL;
	AudioSamples_class = NULL;

	if (init_log() != 0)
		media_log(MEDIA_LOG_WARN, LOG_TAG, "Couldn't init android log");

	p_sdp = env->GetStringUTFChars(sdp, NULL);
	if (p_sdp == NULL) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "OutOfMemoryError");
		return -1;
	}

	cls = env->GetObjectClass(audioReceiver);

	audio_mid = env->GetMethodID(cls, "putAudioSamplesRx",
				"(Lcom/kurento/kas/media/rx/AudioSamples;)V");
	if (audio_mid == 0) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
			"(Lcom/kurento/kas/media/rx/AudioSamples;)V no exists");
		ret = -2;
		goto end;
	}

	AudioSamples_class = env->FindClass("com/kurento/kas/media/rx/AudioSamples");
	if (!AudioSamples_class) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG,
				"com/kurento/kas/media/rx/AudioSamples not found");
		ret = -3;
		goto end;
	}

	AudioSamples_init_mid = env->GetMethodID(AudioSamples_class,
							"<init>", "([BIIIJJJI)V");
	if (!AudioSamples_init_mid) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "init([BIIIJJJI)V not found");
		ret = -4;
		goto end;
	}

	audio_env = env;
	audio_receiver = audioReceiver;
	audioMediaPort = (MediaPort*)audioMediaPortRef;

	try {
		aRxObj = new AudioRx(audioMediaPort, p_sdp, maxDelay, &android_put_audio_samples_rx);
		aRxObj->start();
	}
	catch(MediaException &e) {
		media_log(MEDIA_LOG_ERROR, LOG_TAG, "exception %p: %s", &e, e.what());
	}
end:
	env->DeleteLocalRef(cls);
	env->DeleteLocalRef(audio_receiver);
	env->DeleteLocalRef(AudioSamples_class);
	env->ReleaseStringUTFChars(sdp, p_sdp);

	return ret;
}

JNIEXPORT jint JNICALL
Java_com_kurento_kas_media_rx_MediaRx_stopAudioRx(JNIEnv* env, jclass clazz)
{
	if (aRxObj) {
		aRxObj->stop();
		delete aRxObj;
		aRxObj = NULL;
	}
	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <irrKlang.h>
#include <windows.h>

using namespace irrklang;

int main(int argc, const char** argv)
{
  // start irrKlang with default parameters
  ISoundEngine* engine = createIrrKlangDevice();

  if (!engine)
    return 0; // error starting up the engine

   char i = 0;

  engine->play2D("D:\\Dropbox\\Projet_Lecteur\\media\\08_Iron_Hand.flac"); // Lancement de la musique

  // Test Modification du Volume
  engine->setSoundVolume(0.5);                                             //Met le volume a 0.5
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(0);                                               //Met le volume a 0
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(0.5);                                             //Met le volume a 0.5
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(1);                                               //Met le volume a 1

  // Test Mise en Pause et Play
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setAllSoundsPaused(true);                                        //Met la musique en pause

  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setAllSoundsPaused(false);                                       //Remet la musique en route

  // Test Changement de Musique
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->removeAllSoundSources();                                         //Supprime les musiques qui sont dans l'objet engine
  engine->play2D("D:\\Dropbox\\Projet_Lecteur\\media\\11_Tourettes.flac", true); // Lancement de la musique en boucle (true)

  // Fermer Programme
  std::cin >> i; // wait for user to press a key
  engine->drop(); // delete engine

  return 0;
}

<commit_msg>Test<commit_after>//Test
//Chanson Kévin
//V0.1
//21/01/2016
//17h12
#include <iostream>
#include <irrKlang.h>
#include <windows.h>

using namespace irrklang;

int main(int argc, const char** argv)
{
  // start irrKlang with default parameters
  ISoundEngine* engine = createIrrKlangDevice();

  if (!engine)
    return 0; // error starting up the engine

   char i = 0;

  engine->play2D("D:\\Dropbox\\Projet_Lecteur\\media\\08_Iron_Hand.flac"); // Lancement de la musique

  // Test Modification du Volume
  engine->setSoundVolume(0.5);                                             //Met le volume a 0.5
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(0);                                               //Met le volume a 0
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(0.5);                                             //Met le volume a 0.5
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setSoundVolume(1);                                               //Met le volume a 1

  // Test Mise en Pause et Play
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setAllSoundsPaused(true);                                        //Met la musique en pause

  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->setAllSoundsPaused(false);                                       //Remet la musique en route

  // Test Changement de Musique
  std::cin >> i;                                                           //Attend que l'utilisateur appuie sur une touche
  engine->removeAllSoundSources();                                         //Supprime les musiques qui sont dans l'objet engine
  engine->play2D("D:\\Dropbox\\Projet_Lecteur\\media\\11_Tourettes.flac", true); // Lancement de la musique en boucle (true)

  // Fermer Programme
  std::cin >> i; // wait for user to press a key
  engine->drop(); // delete engine

  return 0;
}

<|endoftext|>


<commit_before>//
// Arduino library for controlling TI's TLC59711
//
// 21 Feb 2016 by Ulrich Stern
//
// open source (see LICENSE file)
//

#include "Tlc59711.h"
#include <SPI.h>

Tlc59711::Tlc59711(uint16_t numTlc, uint8_t clkPin, uint8_t dataPin):
    numTlc(numTlc), bufferSz(14*numTlc), clkPin(clkPin), dataPin(dataPin),
    buffer((uint16_t*) calloc(bufferSz, 2)), buffer2(0),
    beginCalled(false) {
  setTmgrst();
}

void Tlc59711::begin(bool useSpi, unsigned int postXferDelayMicros) {
  end();
  useSpi_ = useSpi;
  postXferDelayMicros_ = postXferDelayMicros;
  beginCalled = true;
}

void Tlc59711::beginFast(bool bufferXfer, uint32_t spiClock,
    unsigned int postXferDelayMicros) {
  begin(true, postXferDelayMicros);
  bufferXfer_ = bufferXfer;
  SPI.begin();
  SPI.beginTransaction(SPISettings(spiClock, MSBFIRST, SPI_MODE0));
  if (bufferXfer && !buffer2)
    buffer2 = (uint16_t*) malloc(2*bufferSz);
}
void Tlc59711::beginSlow(unsigned int postXferDelayMicros, bool interrupts) {
  begin(false, postXferDelayMicros);
  noInterrupts = !interrupts;
  pinMode(clkPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void Tlc59711::setTmgrst(bool val) {
  // OUTTMG = 1, EXTGCK = 0, TMGRST = 0, DSPRPT = 1, BLANK = 0 -> 0x12
  fc = 0x12 + (val ? 0x4 : 0);
  setBrightness();
}

void Tlc59711::setBrightness(uint16_t tlcIdx,
    uint8_t bcr, uint8_t bcg, uint8_t bcb) {
  if (tlcIdx < numTlc) {
    uint32_t ms32 = (uint32_t)0x25 << 26 | (uint32_t)fc << 21 |
      (uint32_t)bcb << 14 | (uint32_t)bcg << 7 | bcr;
    uint16_t idx = 14*tlcIdx+12;
    buffer[idx] = ms32;
    buffer[++idx] = ms32 >> 16;
  }
}
void Tlc59711::setBrightness(uint8_t bcr, uint8_t bcg, uint8_t bcb) {
  for (uint16_t i=0; i<numTlc; i++)
    setBrightness(i, bcr, bcg, bcb);
}

void Tlc59711::setChannel(uint16_t idx, uint16_t val) {
  idx = 14*(idx/12) + idx%12;
  if (idx < bufferSz)
    buffer[idx] = val;
}

void Tlc59711::setRGB(uint16_t idx, uint16_t r, uint16_t g, uint16_t b) {
  idx = 3*idx;
  setChannel(idx, r);
  setChannel(++idx, g);
  setChannel(++idx, b);
}
void Tlc59711::setRGB(uint16_t r, uint16_t g, uint16_t b) {
  for (uint16_t i=0, n=4*numTlc; i<n; i++)
    setRGB(i, r, g, b);
}

static void reverseMemcpy(void *dst, void *src, size_t count) {
  uint8_t* s = (uint8_t*)src;
  while (count-- > 0)
    *((uint8_t*)dst+count) = *s++;
}

void Tlc59711::xferSpi() {
  reverseMemcpy(buffer2, buffer, bufferSz*2);
  cli();
  SPI.transfer(buffer2, bufferSz*2);
}

void Tlc59711::xferSpi16() {
  cli();
  for (uint16_t i=bufferSz-1; i >= 0; i--)
    SPI.transfer16(buffer[i]);
}

void Tlc59711::xferShiftOut() {
  if (noInterrupts)
    cli();
  for (uint16_t i=bufferSz-1; i >= 0; i--) {
    uint16_t val = buffer[i];
    shiftOut(dataPin, clkPin, MSBFIRST, val >> 8);
    shiftOut(dataPin, clkPin, MSBFIRST, val);
  }
}

void Tlc59711::write() {
  if (!beginCalled)
    return;
  if (useSpi_) {
    if (bufferXfer_)
      xferSpi();
    else
      xferSpi16();
  }
  else
    xferShiftOut();
  sei();
  // delay to make sure the TLC59711s read (latch) their shift registers;
  // the delay required is 8 times the duration between the last two SCKI
  // rising edges (plus 1.34 us); see datasheet pg. 22 for details
  delayMicroseconds(postXferDelayMicros_);
}

void Tlc59711::end() {
  if (beginCalled && useSpi_) {
    SPI.endTransaction();
    SPI.end();
  }
}

<commit_msg>fixed bug introduced in 314cd984099ff23fd36c4bfcbc3e1768cb73006f<commit_after>//
// Arduino library for controlling TI's TLC59711
//
// 21 Feb 2016 by Ulrich Stern
//
// open source (see LICENSE file)
//

#include "Tlc59711.h"
#include <SPI.h>

Tlc59711::Tlc59711(uint16_t numTlc, uint8_t clkPin, uint8_t dataPin):
    numTlc(numTlc), bufferSz(14*numTlc), clkPin(clkPin), dataPin(dataPin),
    buffer((uint16_t*) calloc(bufferSz, 2)), buffer2(0),
    beginCalled(false) {
  setTmgrst();
}

void Tlc59711::begin(bool useSpi, unsigned int postXferDelayMicros) {
  end();
  useSpi_ = useSpi;
  postXferDelayMicros_ = postXferDelayMicros;
  beginCalled = true;
}

void Tlc59711::beginFast(bool bufferXfer, uint32_t spiClock,
    unsigned int postXferDelayMicros) {
  begin(true, postXferDelayMicros);
  bufferXfer_ = bufferXfer;
  SPI.begin();
  SPI.beginTransaction(SPISettings(spiClock, MSBFIRST, SPI_MODE0));
  if (bufferXfer && !buffer2)
    buffer2 = (uint16_t*) malloc(2*bufferSz);
}
void Tlc59711::beginSlow(unsigned int postXferDelayMicros, bool interrupts) {
  begin(false, postXferDelayMicros);
  noInterrupts = !interrupts;
  pinMode(clkPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void Tlc59711::setTmgrst(bool val) {
  // OUTTMG = 1, EXTGCK = 0, TMGRST = 0, DSPRPT = 1, BLANK = 0 -> 0x12
  fc = 0x12 + (val ? 0x4 : 0);
  setBrightness();
}

void Tlc59711::setBrightness(uint16_t tlcIdx,
    uint8_t bcr, uint8_t bcg, uint8_t bcb) {
  if (tlcIdx < numTlc) {
    uint32_t ms32 = (uint32_t)0x25 << 26 | (uint32_t)fc << 21 |
      (uint32_t)bcb << 14 | (uint32_t)bcg << 7 | bcr;
    uint16_t idx = 14*tlcIdx+12;
    buffer[idx] = ms32;
    buffer[++idx] = ms32 >> 16;
  }
}
void Tlc59711::setBrightness(uint8_t bcr, uint8_t bcg, uint8_t bcb) {
  for (uint16_t i=0; i<numTlc; i++)
    setBrightness(i, bcr, bcg, bcb);
}

void Tlc59711::setChannel(uint16_t idx, uint16_t val) {
  idx = 14*(idx/12) + idx%12;
  if (idx < bufferSz)
    buffer[idx] = val;
}

void Tlc59711::setRGB(uint16_t idx, uint16_t r, uint16_t g, uint16_t b) {
  idx = 3*idx;
  setChannel(idx, r);
  setChannel(++idx, g);
  setChannel(++idx, b);
}
void Tlc59711::setRGB(uint16_t r, uint16_t g, uint16_t b) {
  for (uint16_t i=0, n=4*numTlc; i<n; i++)
    setRGB(i, r, g, b);
}

static void reverseMemcpy(void *dst, void *src, size_t count) {
  uint8_t* s = (uint8_t*)src;
  while (count-- > 0)
    *((uint8_t*)dst+count) = *s++;
}

void Tlc59711::xferSpi() {
  reverseMemcpy(buffer2, buffer, bufferSz*2);
  cli();
  SPI.transfer(buffer2, bufferSz*2);
}

void Tlc59711::xferSpi16() {
  cli();
  for (int i=bufferSz-1; i >= 0; i--)
    SPI.transfer16(buffer[i]);
}

void Tlc59711::xferShiftOut() {
  if (noInterrupts)
    cli();
  for (int i=bufferSz-1; i >= 0; i--) {
    uint16_t val = buffer[i];
    shiftOut(dataPin, clkPin, MSBFIRST, val >> 8);
    shiftOut(dataPin, clkPin, MSBFIRST, val);
  }
}

void Tlc59711::write() {
  if (!beginCalled)
    return;
  if (useSpi_) {
    if (bufferXfer_)
      xferSpi();
    else
      xferSpi16();
  }
  else
    xferShiftOut();
  sei();
  // delay to make sure the TLC59711s read (latch) their shift registers;
  // the delay required is 8 times the duration between the last two SCKI
  // rising edges (plus 1.34 us); see datasheet pg. 22 for details
  delayMicroseconds(postXferDelayMicros_);
}

void Tlc59711::end() {
  if (beginCalled && useSpi_) {
    SPI.endTransaction();
    SPI.end();
  }
}

<|endoftext|>