<commit_before>/**
 * This file is part of the CernVM File System.
 */
#define __STDC_FORMAT_MACROS
#include "authz_curl.h"

#include <openssl/err.h>
#include <openssl/ssl.h>
#include <pthread.h>

#include <cassert>

#include "authz/authz_session.h"
#include "duplex_curl.h"
#include "duplex_ssl.h"
#include "logging.h"
#include "util/pointer.h"
#include "util_concurrency.h"

using namespace std;  // NOLINT

namespace {

struct sslctx_info {
  sslctx_info() : chain(NULL), pkey(NULL) {}

  STACK_OF(X509) *chain;
  EVP_PKEY *pkey;
};

struct bearer_info {
  /**
  * List of extra headers to put on the HTTP request.  This is required
  * in order to add the "Authorization: Bearer XXXXX" header.
  */
  struct curl_slist *list;

  /**
  * Actual text of the bearer token
  */
  char* token;

};
}  // anonymous namespace

bool AuthzAttachment::ssl_strings_loaded_ = false;

AuthzAttachment::AuthzAttachment(AuthzSessionManager *sm)
  : authz_session_manager_(sm)
{
  // Required for logging OpenSSL errors
  SSL_load_error_strings();
  ssl_strings_loaded_ = true;
}

CURLcode AuthzAttachment::CallbackSslCtx(
  CURL *curl,
  void *sslctx,
  void *parm)
{
  sslctx_info *p = reinterpret_cast<sslctx_info *>(parm);
  SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(sslctx);

  if (parm == NULL)
    return CURLE_OK;

  STACK_OF(X509) *chain = p->chain;
  EVP_PKEY *pkey = p->pkey;

  LogCvmfs(kLogAuthz, kLogDebug, "Customizing OpenSSL context.");

  int cert_count = sk_X509_num(chain);
  if (cert_count == 0) {
    LogOpenSSLErrors("No certificate found in chain.");
  }
  X509 *cert = sk_X509_value(chain, 0);

  // NOTE: SSL_CTX_use_certificate and _user_PrivateKey increase the ref count.
  if (!SSL_CTX_use_certificate(ctx, cert)) {
    LogOpenSSLErrors("Failed to set the user certificate in the SSL "
                     "connection");
    return CURLE_SSL_CERTPROBLEM;
  }

  if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
    LogOpenSSLErrors("Failed to set the private key in the SSL connection");
    return CURLE_SSL_CERTPROBLEM;
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    LogOpenSSLErrors("Provided certificate and key do not match");
    return CURLE_SSL_CERTPROBLEM;
  } else {
    LogCvmfs(kLogAuthz, kLogDebug, "Client certificate and key match.");
  }

  // NOTE: SSL_CTX_add_extra_chain_cert DOES NOT increase the ref count
  // Instead, it now owns the pointer.  THIS IS DIFFERENT FROM ABOVE.
  for (int idx = 1; idx < cert_count; idx++) {
    cert = sk_X509_value(chain, idx);
    if (!SSL_CTX_add_extra_chain_cert(ctx, X509_dup(cert))) {
      LogOpenSSLErrors("Failed to add client cert to chain");
    }
  }

  return CURLE_OK;
}

bool AuthzAttachment::ConfigureSciTokenCurl(
  CURL *curl_handle,
  const AuthzToken &token,
  void **info_data)
{
  if (*info_data == NULL) {
    AuthzToken* saved_token = new AuthzToken();
    saved_token->type = kTokenBearer;
    saved_token->data = new bearer_info;
    bearer_info* bearer = static_cast<bearer_info*>(saved_token->data);
    bearer->token = (char*)smalloc((sizeof(char) * token.size)+ 1);
    memcpy(bearer->token, token.data, token.size);
    static_cast<char*>(bearer->token)[token.size] = 0;
    *info_data = saved_token;
  }

  AuthzToken* tmp_token = static_cast<AuthzToken*>(*info_data);
  bearer_info* bearer = static_cast<bearer_info*>(tmp_token->data);

  LogCvmfs(kLogAuthz, kLogDebug, "Setting OAUTH bearer token to: %s",
           static_cast<char*>(bearer->token));

  // Create the Bearer token
  // The CURLOPT_XOAUTH2_BEARER option only works "IMAP, POP3 and SMTP" protocols
  // Not HTTPS
  std::string auth_preamble = "Authorization: Bearer ";
  std::string auth_header = auth_preamble + static_cast<char*>(bearer->token);
  bearer->list = curl_slist_append(bearer->list, auth_header.c_str());
  int retval = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, bearer->list);

  if (retval != CURLE_OK) {
    LogCvmfs(kLogAuthz, kLogSyslogErr, "Failed to set Oauth2 Bearer Token");
    return false;
  }

  return true;
}

bool AuthzAttachment::ConfigureCurlHandle(
  CURL *curl_handle,
  pid_t pid,
  void **info_data)
{
  assert(info_data);

  // We cannot rely on libcurl to pipeline (yet), as cvmfs may
  // bounce between different auth handles.
  curl_easy_setopt(curl_handle, CURLOPT_FRESH_CONNECT, 1);
  curl_easy_setopt(curl_handle, CURLOPT_FORBID_REUSE, 1);
  curl_easy_setopt(curl_handle, CURLOPT_SSL_SESSIONID_CACHE, 0);

  UniquePtr<AuthzToken> token(
    authz_session_manager_->GetTokenCopy(pid, membership_));
  if (!token.IsValid()) {
    LogCvmfs(kLogAuthz, kLogDebug, "failed to get authz token for pid %d", pid);
    return false;
  }

  switch (token->type) {
    case kTokenBearer:
      // If it's a scitoken, then just go to the private
      // ConfigureSciTokenCurl function
      return ConfigureSciTokenCurl(curl_handle, *token, info_data);

    case kTokenX509:
      // The x509 code is below, so just break and go.
      break;

    default:
      // Oh no, don't know the the token type, throw error and return
      LogCvmfs(kLogAuthz, kLogDebug, "unknown token type: %d", token->type);
      return false;
  }

  curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA, NULL);

  // The calling layer is reusing data;
  if (*info_data) {
    curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA,
                     static_cast<AuthzToken*>(*info_data)->data);
    return true;
  }

  int retval = curl_easy_setopt(curl_handle,
                                CURLOPT_SSL_CTX_FUNCTION,
                                CallbackSslCtx);
  if (retval != CURLE_OK) {
    LogCvmfs(kLogAuthz, kLogDebug, "cannot configure curl ssl callback");
    return false;
  }

  UniquePtr<sslctx_info> parm(new sslctx_info);

  STACK_OF(X509_INFO) *sk = NULL;
  STACK_OF(X509) *certstack = sk_X509_new_null();
  parm->chain = certstack;
  if (certstack == NULL) {
    LogCvmfs(kLogAuthz, kLogSyslogErr, "Failed to allocate new X509 chain.");
    return false;
  }

  BIO *bio_token = BIO_new_mem_buf(token->data, token->size);
  assert(bio_token != NULL);
  sk = PEM_X509_INFO_read_bio(bio_token, NULL, NULL, NULL);
  BIO_free(bio_token);
  if (!sk) {
    LogOpenSSLErrors("Failed to load credential file.");
    sk_X509_INFO_free(sk);
    sk_X509_free(certstack);
    return false;
  }

  while (sk_X509_INFO_num(sk)) {
    X509_INFO *xi = sk_X509_INFO_shift(sk);
    if (xi == NULL) {continue;}
    if (xi->x509 != NULL) {
#ifdef OPENSSL_API_INTERFACE_V11
      retval = X509_up_ref(xi->x509);
      assert(retval == 1);
#else
      CRYPTO_add(&xi->x509->references, 1, CRYPTO_LOCK_X509);
#endif
      sk_X509_push(certstack, xi->x509);
    }
    if ((xi->x_pkey != NULL) && (xi->x_pkey->dec_pkey != NULL)) {
      parm->pkey = xi->x_pkey->dec_pkey;
#ifdef OPENSSL_API_INTERFACE_V11
      retval = EVP_PKEY_up_ref(parm->pkey);
      assert(retval == 1);
#else
      CRYPTO_add(&parm->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
    }
    X509_INFO_free(xi);
  }
  sk_X509_INFO_free(sk);

  if (parm->pkey == NULL) {
    // Sigh - PEM_X509_INFO_read doesn't understand old key encodings.
    // Try a more general-purpose funciton.
    BIO *bio_token = BIO_new_mem_buf(token->data, token->size);
    assert(bio_token != NULL);
    EVP_PKEY *old_pkey = PEM_read_bio_PrivateKey(bio_token, NULL, NULL, NULL);
    BIO_free(bio_token);
    if (old_pkey) {
      parm->pkey = old_pkey;
    } else {
      sk_X509_free(certstack);
      LogCvmfs(kLogAuthz, kLogSyslogErr,
               "credential did not contain a decrypted private key.");
      return false;
    }
  }

  if (!sk_X509_num(certstack)) {
    EVP_PKEY_free(parm->pkey);
    sk_X509_free(certstack);
    LogCvmfs(kLogAuthz, kLogSyslogErr,
             "Credential file did not contain any actual credentials.");
    return false;
  } else {
    LogCvmfs(kLogAuthz, kLogDebug, "Certificate stack contains %d entries.",
             sk_X509_num(certstack));
  }

  AuthzToken* to_return = new AuthzToken();
  to_return->type = kTokenX509;
  to_return->data = static_cast<void*>(parm.Release());
  curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA,
                   static_cast<sslctx_info*>(to_return->data));
  *info_data = to_return;
  return true;
}

void AuthzAttachment::LogOpenSSLErrors(const char *top_message) {
  assert(ssl_strings_loaded_);
  char error_buf[1024];
  LogCvmfs(kLogAuthz, kLogSyslogWarn, "%s", top_message);
  unsigned long next_err;  // NOLINT; this is the type expected by OpenSSL
  while ((next_err = ERR_get_error())) {
    ERR_error_string_n(next_err, error_buf, 1024);
    LogCvmfs(kLogAuthz, kLogSyslogErr, "%s", error_buf);
  }
}

void AuthzAttachment::ReleaseCurlHandle(CURL *curl_handle, void *info_data) {
  assert(info_data);

  AuthzToken* token = static_cast<AuthzToken*>(info_data);
  if (token->type == kTokenBearer) {
    // Compiler complains if we delete a void*
    bearer_info* bearer = static_cast<bearer_info*>(token->data);
    delete static_cast<char*>(bearer->token);
    curl_slist_free_all(bearer->list);
    delete static_cast<bearer_info*>(token->data);
    token->data = NULL;
    delete token;

  } else if (token->type == kTokenX509) {
    sslctx_info *p = static_cast<sslctx_info *>(info_data);
    STACK_OF(X509) *chain = p->chain;
    EVP_PKEY *pkey = p->pkey;
    p->chain = NULL;
    p->pkey = NULL;
    delete p;

    // Calls X509_free on each element, then frees the stack itself
    sk_X509_pop_free(chain, X509_free);
    EVP_PKEY_free(pkey);

    // Make sure that if CVMFS reuses this curl handle, curl doesn't try
    // to reuse cert chain we just freed.
    curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA, 0);
  }
}
<commit_msg>Fixing some cpplint<commit_after>/**
 * This file is part of the CernVM File System.
 */
#define __STDC_FORMAT_MACROS
#include "authz_curl.h"

#include <openssl/err.h>
#include <openssl/ssl.h>
#include <pthread.h>

#include <cassert>

#include "authz/authz_session.h"
#include "duplex_curl.h"
#include "duplex_ssl.h"
#include "logging.h"
#include "util/pointer.h"
#include "util_concurrency.h"

using namespace std;  // NOLINT

namespace {

struct sslctx_info {
  sslctx_info() : chain(NULL), pkey(NULL) {}

  STACK_OF(X509) *chain;
  EVP_PKEY *pkey;
};

struct bearer_info {
  /**
  * List of extra headers to put on the HTTP request.  This is required
  * in order to add the "Authorization: Bearer XXXXX" header.
  */
  struct curl_slist *list;

  /**
  * Actual text of the bearer token
  */
  char* token;
};
}  // anonymous namespace

bool AuthzAttachment::ssl_strings_loaded_ = false;

AuthzAttachment::AuthzAttachment(AuthzSessionManager *sm)
  : authz_session_manager_(sm)
{
  // Required for logging OpenSSL errors
  SSL_load_error_strings();
  ssl_strings_loaded_ = true;
}

CURLcode AuthzAttachment::CallbackSslCtx(
  CURL *curl,
  void *sslctx,
  void *parm)
{
  sslctx_info *p = reinterpret_cast<sslctx_info *>(parm);
  SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(sslctx);

  if (parm == NULL)
    return CURLE_OK;

  STACK_OF(X509) *chain = p->chain;
  EVP_PKEY *pkey = p->pkey;

  LogCvmfs(kLogAuthz, kLogDebug, "Customizing OpenSSL context.");

  int cert_count = sk_X509_num(chain);
  if (cert_count == 0) {
    LogOpenSSLErrors("No certificate found in chain.");
  }
  X509 *cert = sk_X509_value(chain, 0);

  // NOTE: SSL_CTX_use_certificate and _user_PrivateKey increase the ref count.
  if (!SSL_CTX_use_certificate(ctx, cert)) {
    LogOpenSSLErrors("Failed to set the user certificate in the SSL "
                     "connection");
    return CURLE_SSL_CERTPROBLEM;
  }

  if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
    LogOpenSSLErrors("Failed to set the private key in the SSL connection");
    return CURLE_SSL_CERTPROBLEM;
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    LogOpenSSLErrors("Provided certificate and key do not match");
    return CURLE_SSL_CERTPROBLEM;
  } else {
    LogCvmfs(kLogAuthz, kLogDebug, "Client certificate and key match.");
  }

  // NOTE: SSL_CTX_add_extra_chain_cert DOES NOT increase the ref count
  // Instead, it now owns the pointer.  THIS IS DIFFERENT FROM ABOVE.
  for (int idx = 1; idx < cert_count; idx++) {
    cert = sk_X509_value(chain, idx);
    if (!SSL_CTX_add_extra_chain_cert(ctx, X509_dup(cert))) {
      LogOpenSSLErrors("Failed to add client cert to chain");
    }
  }

  return CURLE_OK;
}

bool AuthzAttachment::ConfigureSciTokenCurl(
  CURL *curl_handle,
  const AuthzToken &token,
  void **info_data)
{
  if (*info_data == NULL) {
    AuthzToken* saved_token = new AuthzToken();
    saved_token->type = kTokenBearer;
    saved_token->data = new bearer_info;
    bearer_info* bearer = static_cast<bearer_info*>(saved_token->data);
    bearer->list = NULL;
    bearer->token = static_cast<char*>(smalloc((sizeof(char) * token.size)+ 1));
    memcpy(bearer->token, token.data, token.size);
    static_cast<char*>(bearer->token)[token.size] = 0;
    *info_data = saved_token;
  }

  AuthzToken* tmp_token = static_cast<AuthzToken*>(*info_data);
  bearer_info* bearer = static_cast<bearer_info*>(tmp_token->data);

  LogCvmfs(kLogAuthz, kLogDebug, "Setting OAUTH bearer token to: %s",
           static_cast<char*>(bearer->token));

  // Create the Bearer token
  // The CURLOPT_XOAUTH2_BEARER option only works "IMAP, POP3 and SMTP"
  // protocols. Not HTTPS
  std::string auth_preamble = "Authorization: Bearer ";
  std::string auth_header = auth_preamble + static_cast<char*>(bearer->token);
  bearer->list = curl_slist_append(bearer->list, auth_header.c_str());
  int retval = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, bearer->list);

  if (retval != CURLE_OK) {
    LogCvmfs(kLogAuthz, kLogSyslogErr, "Failed to set Oauth2 Bearer Token");
    return false;
  }

  return true;
}

bool AuthzAttachment::ConfigureCurlHandle(
  CURL *curl_handle,
  pid_t pid,
  void **info_data)
{
  assert(info_data);

  // We cannot rely on libcurl to pipeline (yet), as cvmfs may
  // bounce between different auth handles.
  curl_easy_setopt(curl_handle, CURLOPT_FRESH_CONNECT, 1);
  curl_easy_setopt(curl_handle, CURLOPT_FORBID_REUSE, 1);
  curl_easy_setopt(curl_handle, CURLOPT_SSL_SESSIONID_CACHE, 0);

  UniquePtr<AuthzToken> token(
    authz_session_manager_->GetTokenCopy(pid, membership_));
  if (!token.IsValid()) {
    LogCvmfs(kLogAuthz, kLogDebug, "failed to get authz token for pid %d", pid);
    return false;
  }

  switch (token->type) {
    case kTokenBearer:
      // If it's a scitoken, then just go to the private
      // ConfigureSciTokenCurl function
      return ConfigureSciTokenCurl(curl_handle, *token, info_data);

    case kTokenX509:
      // The x509 code is below, so just break and go.
      break;

    default:
      // Oh no, don't know the the token type, throw error and return
      LogCvmfs(kLogAuthz, kLogDebug, "unknown token type: %d", token->type);
      return false;
  }

  curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA, NULL);

  // The calling layer is reusing data;
  if (*info_data) {
    curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA,
                     static_cast<AuthzToken*>(*info_data)->data);
    return true;
  }

  int retval = curl_easy_setopt(curl_handle,
                                CURLOPT_SSL_CTX_FUNCTION,
                                CallbackSslCtx);
  if (retval != CURLE_OK) {
    LogCvmfs(kLogAuthz, kLogDebug, "cannot configure curl ssl callback");
    return false;
  }

  UniquePtr<sslctx_info> parm(new sslctx_info);

  STACK_OF(X509_INFO) *sk = NULL;
  STACK_OF(X509) *certstack = sk_X509_new_null();
  parm->chain = certstack;
  if (certstack == NULL) {
    LogCvmfs(kLogAuthz, kLogSyslogErr, "Failed to allocate new X509 chain.");
    return false;
  }

  BIO *bio_token = BIO_new_mem_buf(token->data, token->size);
  assert(bio_token != NULL);
  sk = PEM_X509_INFO_read_bio(bio_token, NULL, NULL, NULL);
  BIO_free(bio_token);
  if (!sk) {
    LogOpenSSLErrors("Failed to load credential file.");
    sk_X509_INFO_free(sk);
    sk_X509_free(certstack);
    return false;
  }

  while (sk_X509_INFO_num(sk)) {
    X509_INFO *xi = sk_X509_INFO_shift(sk);
    if (xi == NULL) {continue;}
    if (xi->x509 != NULL) {
#ifdef OPENSSL_API_INTERFACE_V11
      retval = X509_up_ref(xi->x509);
      assert(retval == 1);
#else
      CRYPTO_add(&xi->x509->references, 1, CRYPTO_LOCK_X509);
#endif
      sk_X509_push(certstack, xi->x509);
    }
    if ((xi->x_pkey != NULL) && (xi->x_pkey->dec_pkey != NULL)) {
      parm->pkey = xi->x_pkey->dec_pkey;
#ifdef OPENSSL_API_INTERFACE_V11
      retval = EVP_PKEY_up_ref(parm->pkey);
      assert(retval == 1);
#else
      CRYPTO_add(&parm->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
#endif
    }
    X509_INFO_free(xi);
  }
  sk_X509_INFO_free(sk);

  if (parm->pkey == NULL) {
    // Sigh - PEM_X509_INFO_read doesn't understand old key encodings.
    // Try a more general-purpose funciton.
    BIO *bio_token = BIO_new_mem_buf(token->data, token->size);
    assert(bio_token != NULL);
    EVP_PKEY *old_pkey = PEM_read_bio_PrivateKey(bio_token, NULL, NULL, NULL);
    BIO_free(bio_token);
    if (old_pkey) {
      parm->pkey = old_pkey;
    } else {
      sk_X509_free(certstack);
      LogCvmfs(kLogAuthz, kLogSyslogErr,
               "credential did not contain a decrypted private key.");
      return false;
    }
  }

  if (!sk_X509_num(certstack)) {
    EVP_PKEY_free(parm->pkey);
    sk_X509_free(certstack);
    LogCvmfs(kLogAuthz, kLogSyslogErr,
             "Credential file did not contain any actual credentials.");
    return false;
  } else {
    LogCvmfs(kLogAuthz, kLogDebug, "Certificate stack contains %d entries.",
             sk_X509_num(certstack));
  }

  AuthzToken* to_return = new AuthzToken();
  to_return->type = kTokenX509;
  to_return->data = static_cast<void*>(parm.Release());
  curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA,
                   static_cast<sslctx_info*>(to_return->data));
  *info_data = to_return;
  return true;
}

void AuthzAttachment::LogOpenSSLErrors(const char *top_message) {
  assert(ssl_strings_loaded_);
  char error_buf[1024];
  LogCvmfs(kLogAuthz, kLogSyslogWarn, "%s", top_message);
  unsigned long next_err;  // NOLINT; this is the type expected by OpenSSL
  while ((next_err = ERR_get_error())) {
    ERR_error_string_n(next_err, error_buf, 1024);
    LogCvmfs(kLogAuthz, kLogSyslogErr, "%s", error_buf);
  }
}

void AuthzAttachment::ReleaseCurlHandle(CURL *curl_handle, void *info_data) {
  assert(info_data);

  AuthzToken* token = static_cast<AuthzToken*>(info_data);
  if (token->type == kTokenBearer) {
    // Compiler complains if we delete a void*
    bearer_info* bearer = static_cast<bearer_info*>(token->data);
    delete static_cast<char*>(bearer->token);
    curl_slist_free_all(bearer->list);
    delete static_cast<bearer_info*>(token->data);
    token->data = NULL;
    delete token;

  } else if (token->type == kTokenX509) {
    sslctx_info *p = static_cast<sslctx_info *>(info_data);
    STACK_OF(X509) *chain = p->chain;
    EVP_PKEY *pkey = p->pkey;
    p->chain = NULL;
    p->pkey = NULL;
    delete p;

    // Calls X509_free on each element, then frees the stack itself
    sk_X509_pop_free(chain, X509_free);
    EVP_PKEY_free(pkey);

    // Make sure that if CVMFS reuses this curl handle, curl doesn't try
    // to reuse cert chain we just freed.
    curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA, 0);
  }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/hw_access_def.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file hw_access_def.H
/// @brief Hardware access definitions
///

#ifndef FAPI2_HWACCESSDEF_H_
#define FAPI2_HWACCESSDEF_H_

#include <stdint.h>

/// @cond
typedef uint64_t spyId_t;
typedef uint64_t scanRingId_t;
/// @endcond

namespace fapi2
{
///
/// @enum fapi2::ChipOpModifyMode
/// @brief Enumeration of modify modes used in HW access modify operations
///
enum ChipOpModifyMode
{
    CHIP_OP_MODIFY_MODE_OR = 1,  ///< Modify or mode
    CHIP_OP_MODIFY_MODE_AND = 2, ///< Modify and mode
    CHIP_OP_MODIFY_MODE_XOR = 3, ///< Modify xor mode
};

///
/// @enum fapi2::RingMode
/// @brief Enumeration of Ring access operation modes
///        This is a bitmap to allow the user to specify multiple modes.
///
enum RingMode
{
    RING_MODE_SET_PULSE       = 0x00000001, ///< Set pulse
    RING_MODE_NO_HEADER_CHECK = 0x00000002, ///< Dont' check header
    // FUTURE_MODE            = 0x00000004,
    // FUTURE_MODE            = 0x00000008,
};

/// @enum OpModes operational Mode Error Functions
enum OpModes
{
    // These are bit-masks in case they need to be or'd together
    NORMAL           = 0x00,
    IGNORE_HW_ERROR  = 0x01,
    DO_NOT_DO_WAKEUP = 0x02,
};

}

#endif
<commit_msg>Updates to the fapi2 putRing API<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/hw_access_def.H $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file hw_access_def.H
/// @brief Hardware access definitions
///

#ifndef FAPI2_HWACCESSDEF_H_
#define FAPI2_HWACCESSDEF_H_

#include <stdint.h>

/// @cond
typedef uint64_t spyId_t;
typedef uint64_t scanRingId_t;
/// @endcond

namespace fapi2
{
///
/// @enum fapi2::ChipOpModifyMode
/// @brief Enumeration of modify modes used in HW access modify operations
///
enum ChipOpModifyMode
{
    CHIP_OP_MODIFY_MODE_OR = 1,  ///< Modify or mode
    CHIP_OP_MODIFY_MODE_AND = 2, ///< Modify and mode
    CHIP_OP_MODIFY_MODE_XOR = 3, ///< Modify xor mode
};

///
/// @enum fapi2::RingMode
/// @brief Enumeration of Ring access operation modes
///        This is a bitmap to allow the user to specify multiple modes.
///
enum RingMode
{
    RING_MODE_HEADER_CHECK    = 0x00000000, ///< Check header
    RING_MODE_SET_PULSE       = 0x00000001, ///< Set pulse
    RING_MODE_NO_HEADER_CHECK = 0x00000002, ///< Dont' check header
    // FUTURE_MODE            = 0x00000004,
    // FUTURE_MODE            = 0x00000008,
};

/// @enum OpModes operational Mode Error Functions
enum OpModes
{
    // These are bit-masks in case they need to be or'd together
    NORMAL           = 0x00,
    IGNORE_HW_ERROR  = 0x01,
    DO_NOT_DO_WAKEUP = 0x02,
};

}

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2006, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/file_pool.hpp"

#include <boost/bind.hpp>

using namespace libtorrent;

// do not include files and folders whose
// name starts with a .
bool file_filter(std::string const& f)
{
	if (filename(f)[0] == '.') return false;
	fprintf(stderr, "%s\n", f.c_str());
	return true;
}

void print_progress(int i, int num)
{
	fprintf(stderr, "\r%d/%d", i+1, num);
}

void print_usage()
{
	fputs("usage: make_torrent FILE [OPTIONS]\n"
		"\n"
		"Generates a torrent file from the specified file\n"
		"or directory and writes it to standard out\n\n"
		"OPTIONS:\n"
		"-m file     generate a merkle hash tree torrent.\n"
		"            merkle torrents require client support\n"
		"            the resulting full merkle tree is written to\n"
		"            the specified file\n"
		"-f          include sha-1 file hashes in the torrent\n"
		"            this helps supporting mixing sources from\n"
		"            other networks\n"
		"-w url      adds a web seed to the torrent with\n"
		"            the specified url\n"
		"-t url      adds the specified tracker to the\n"
		"            torrent. For multiple trackers, specify more\n"
		"            -t options\n"
		"-C creator  sets the created-by field to the specified string\n"
		"-p bytes    enables padding files. Files larger\n"
		"            than bytes will be piece-aligned\n"
		"-s bytes    specifies a piece size for the torrent\n"
		"            This has to be a multiple of 16 kiB\n"
		"-l          Don't follow symlinks, instead encode them as\n"
		"            links in the torrent file\n"
		"-o file     specifies the output filename of the torrent file\n"
		"            If this is not specified, the torrent file is\n"
		"            printed to the standard out, except on windows\n"
		"            where the filename defaults to a.torrent\n"
		"-c file     add root certificate to the torrent, to verify\n"
		"            the HTTPS tracker\n"
		, stderr);
}

int main(int argc, char* argv[])
{
	using namespace libtorrent;

	std::string creator_str = "libtorrent";

	if (argc < 2)
	{
		print_usage();
		return 1;
	}

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		std::vector<std::string> web_seeds;
		std::vector<std::string> trackers;
		int pad_file_limit = -1;
		int piece_size = 0;
		int flags = 0;
		std::string root_cert;

		std::string outfile;
		std::string merklefile;
#ifdef TORRENT_WINDOWS
		// don't ever write binary data to the console on windows
		// it will just be interpreted as text and corrupted
		outfile = "a.torrent";
#endif

		for (int i = 2; i < argc; ++i)
		{
			if (argv[i][0] != '-')
			{
				print_usage();
				return 1;
			}

			switch (argv[i][1])
			{
				case 'w':
					++i;
					web_seeds.push_back(argv[i]);
					break;
				case 't':
					++i;
					trackers.push_back(argv[i]);
					break;
				case 'p':
					++i;
					pad_file_limit = atoi(argv[i]);
					flags |= create_torrent::optimize;
					break;
				case 's':
					++i;
					piece_size = atoi(argv[i]);
					break;
				case 'm':
					++i;
					merklefile = argv[i];
					flags |= create_torrent::merkle;
					break;
				case 'o':
					++i;
					outfile = argv[i];
					break;
				case 'f':
					flags |= create_torrent::calculate_file_hashes;
					break;
				case 'l':
					flags |= create_torrent::symlinks;
					break;
				case 'C':
					++i;
					creator_str = argv[i];
					break;
				case 'c':
					++i;
					root_cert = argv[i];
					break;
				default:
					print_usage();
					return 1;
			}
		}

		file_storage fs;
		file_pool fp;
		std::string full_path = libtorrent::complete(argv[1]);

		add_files(fs, full_path, file_filter, flags);
		if (fs.num_files() == 0)
		{
			fputs("no files specified.\n", stderr);
			return 1;
		}

		create_torrent t(fs, piece_size, pad_file_limit, flags);
		int tier = 0;
		for (std::vector<std::string>::iterator i = trackers.begin()
			, end(trackers.end()); i != end; ++i, ++tier)
			t.add_tracker(*i, tier);

		for (std::vector<std::string>::iterator i = web_seeds.begin()
			, end(web_seeds.end()); i != end; ++i)
			t.add_url_seed(*i);

		error_code ec;
		set_piece_hashes(t, parent_path(full_path)
			, boost::bind(&print_progress, _1, t.num_pieces()), ec);
		if (ec)
		{
			fprintf(stderr, "%s\n", ec.message().c_str());
			return 1;
		}

		fprintf(stderr, "\n");
		t.set_creator(creator_str.c_str());

		if (!root_cert.empty())
		{
			std::vector<char> pem;
			load_file(root_cert, pem, ec, 10000);
			if (ec)
			{
				fprintf(stderr, "failed to load root certificate for tracker: %s\n", ec.message().c_str());
			}
			else
			{
				t.set_root_cert(std::string(&pem[0], pem.size()));
			}
		}

		// create the torrent and print it to stdout
		std::vector<char> torrent;
		bencode(back_inserter(torrent), t.generate());
		FILE* output = stdout;
		if (!outfile.empty())
			output = fopen(outfile.c_str(), "wb+");
		if (output == NULL)
		{
			fprintf(stderr, "failed to open file \"%s\": (%d) %s\n"
				, outfile.c_str(), errno, strerror(errno));
			return 1;
		}
		fwrite(&torrent[0], 1, torrent.size(), output);

		if (output != stdout)
			fclose(output);

		if (!merklefile.empty())
		{
			output = fopen(merklefile.c_str(), "wb+");
			int ret = fwrite(&t.merkle_tree()[0], 20, t.merkle_tree().size(), output);
			if (ret != t.merkle_tree().size() * 20)
			{
				fprintf(stderr, "failed to write %s: (%d) %s\n"
					, merklefile.c_str(), errno, strerror(errno));
			}
			fclose(output);
		}

#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception& e)
	{
		fprintf(stderr, "%s\n", e.what());
	}
#endif

	return 0;
}

<commit_msg>support setting comment in make_torrent example<commit_after>/*

Copyright (c) 2006, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/file.hpp"
#include "libtorrent/file_pool.hpp"

#include <boost/bind.hpp>

using namespace libtorrent;

// do not include files and folders whose
// name starts with a .
bool file_filter(std::string const& f)
{
	if (filename(f)[0] == '.') return false;
	fprintf(stderr, "%s\n", f.c_str());
	return true;
}

void print_progress(int i, int num)
{
	fprintf(stderr, "\r%d/%d", i+1, num);
}

void print_usage()
{
	fputs("usage: make_torrent FILE [OPTIONS]\n"
		"\n"
		"Generates a torrent file from the specified file\n"
		"or directory and writes it to standard out\n\n"
		"OPTIONS:\n"
		"-m file     generate a merkle hash tree torrent.\n"
		"            merkle torrents require client support\n"
		"            the resulting full merkle tree is written to\n"
		"            the specified file\n"
		"-f          include sha-1 file hashes in the torrent\n"
		"            this helps supporting mixing sources from\n"
		"            other networks\n"
		"-w url      adds a web seed to the torrent with\n"
		"            the specified url\n"
		"-t url      adds the specified tracker to the\n"
		"            torrent. For multiple trackers, specify more\n"
		"            -t options\n"
		"-c comment  sets the comment to the specified string\n"
		"-C creator  sets the created-by field to the specified string\n"
		"-p bytes    enables padding files. Files larger\n"
		"            than bytes will be piece-aligned\n"
		"-s bytes    specifies a piece size for the torrent\n"
		"            This has to be a multiple of 16 kiB\n"
		"-l          Don't follow symlinks, instead encode them as\n"
		"            links in the torrent file\n"
		"-o file     specifies the output filename of the torrent file\n"
		"            If this is not specified, the torrent file is\n"
		"            printed to the standard out, except on windows\n"
		"            where the filename defaults to a.torrent\n"
		"-r file     add root certificate to the torrent, to verify\n"
		"            the HTTPS tracker\n"
		, stderr);
}

int main(int argc, char* argv[])
{
	using namespace libtorrent;

	std::string creator_str = "libtorrent";
	std::string comment_str;

	if (argc < 2)
	{
		print_usage();
		return 1;
	}

#ifndef BOOST_NO_EXCEPTIONS
	try
	{
#endif
		std::vector<std::string> web_seeds;
		std::vector<std::string> trackers;
		int pad_file_limit = -1;
		int piece_size = 0;
		int flags = 0;
		std::string root_cert;

		std::string outfile;
		std::string merklefile;
#ifdef TORRENT_WINDOWS
		// don't ever write binary data to the console on windows
		// it will just be interpreted as text and corrupted
		outfile = "a.torrent";
#endif

		for (int i = 2; i < argc; ++i)
		{
			if (argv[i][0] != '-')
			{
				print_usage();
				return 1;
			}

			switch (argv[i][1])
			{
				case 'w':
					++i;
					web_seeds.push_back(argv[i]);
					break;
				case 't':
					++i;
					trackers.push_back(argv[i]);
					break;
				case 'p':
					++i;
					pad_file_limit = atoi(argv[i]);
					flags |= create_torrent::optimize;
					break;
				case 's':
					++i;
					piece_size = atoi(argv[i]);
					break;
				case 'm':
					++i;
					merklefile = argv[i];
					flags |= create_torrent::merkle;
					break;
				case 'o':
					++i;
					outfile = argv[i];
					break;
				case 'f':
					flags |= create_torrent::calculate_file_hashes;
					break;
				case 'l':
					flags |= create_torrent::symlinks;
					break;
				case 'C':
					++i;
					creator_str = argv[i];
					break;
				case 'c':
					++i;
					comment_str = argv[i];
					break;
				case 'r':
					++i;
					root_cert = argv[i];
					break;
				default:
					print_usage();
					return 1;
			}
		}

		file_storage fs;
		file_pool fp;
		std::string full_path = libtorrent::complete(argv[1]);

		add_files(fs, full_path, file_filter, flags);
		if (fs.num_files() == 0)
		{
			fputs("no files specified.\n", stderr);
			return 1;
		}

		create_torrent t(fs, piece_size, pad_file_limit, flags);
		int tier = 0;
		for (std::vector<std::string>::iterator i = trackers.begin()
			, end(trackers.end()); i != end; ++i, ++tier)
			t.add_tracker(*i, tier);

		for (std::vector<std::string>::iterator i = web_seeds.begin()
			, end(web_seeds.end()); i != end; ++i)
			t.add_url_seed(*i);

		error_code ec;
		set_piece_hashes(t, parent_path(full_path)
			, boost::bind(&print_progress, _1, t.num_pieces()), ec);
		if (ec)
		{
			fprintf(stderr, "%s\n", ec.message().c_str());
			return 1;
		}

		fprintf(stderr, "\n");
		t.set_creator(creator_str.c_str());
		if (!comment_str.empty())
			t.set_comment(comment_str.c_str());

		if (!root_cert.empty())
		{
			std::vector<char> pem;
			load_file(root_cert, pem, ec, 10000);
			if (ec)
			{
				fprintf(stderr, "failed to load root certificate for tracker: %s\n", ec.message().c_str());
			}
			else
			{
				t.set_root_cert(std::string(&pem[0], pem.size()));
			}
		}

		// create the torrent and print it to stdout
		std::vector<char> torrent;
		bencode(back_inserter(torrent), t.generate());
		FILE* output = stdout;
		if (!outfile.empty())
			output = fopen(outfile.c_str(), "wb+");
		if (output == NULL)
		{
			fprintf(stderr, "failed to open file \"%s\": (%d) %s\n"
				, outfile.c_str(), errno, strerror(errno));
			return 1;
		}
		fwrite(&torrent[0], 1, torrent.size(), output);

		if (output != stdout)
			fclose(output);

		if (!merklefile.empty())
		{
			output = fopen(merklefile.c_str(), "wb+");
			int ret = fwrite(&t.merkle_tree()[0], 20, t.merkle_tree().size(), output);
			if (ret != t.merkle_tree().size() * 20)
			{
				fprintf(stderr, "failed to write %s: (%d) %s\n"
					, merklefile.c_str(), errno, strerror(errno));
			}
			fclose(output);
		}

#ifndef BOOST_NO_EXCEPTIONS
	}
	catch (std::exception& e)
	{
		fprintf(stderr, "%s\n", e.what());
	}
#endif

	return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: skeletonjava.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: jsc $ $Date: 2005-09-09 13:50:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _UNO_DEVTOOLS_SKELETONJAVA_HXX_
#define _UNO_DEVTOOLS_SKELETONJAVA_HXX_

#include <fstream>

#ifndef _CODEMAKER_GENERATEDTYPESET_HXX_
#include <codemaker/generatedtypeset.hxx>
#endif
#ifndef _UNO_DEVTOOLS_SKELETONCOMMON_HXX_
#include "skeletoncommon.hxx"
#endif

namespace skeletonmaker { namespace java {

void printType(std::ostream & o,
               ProgramOptions const & options, TypeManager const & manager,
               codemaker::UnoType::Sort sort, RTTypeClass typeClass,
               rtl::OString const & name, sal_Int32 rank,
               std::vector< rtl::OString > const & arguments,
               bool referenceType, bool defaultvalue=false);

void printType(std::ostream & o,
               ProgramOptions const & options, TypeManager const & manager,
               rtl::OString const & type, bool referenceType,
               bool defaultvalue=false);

bool printConstructorParameters(std::ostream & o,
                                ProgramOptions const & options,
                                TypeManager const & manager,
                                typereg::Reader const & reader,
                                typereg::Reader const & outerReader,
                                std::vector< rtl::OString > const & arguments);

void printConstructor(std::ostream & o,
                      ProgramOptions const & options, TypeManager const & manager,
                      typereg::Reader const & reader,
                      std::vector< rtl::OString > const & arguments);

void printMethodParameters(std::ostream & o,
                           ProgramOptions const & options,
                           TypeManager const & manager,
                           typereg::Reader const & reader,
                           sal_uInt16 method, bool previous,
                           bool withtype,
                           bool shortname=false);

void printExceptionSpecification(std::ostream & o,
                                 ProgramOptions const & options,
                                 TypeManager const & manager,
                                 typereg::Reader const & reader,
                                 sal_uInt16 method);

void printMethods(std::ostream & o,
                  ProgramOptions const & options, TypeManager const & manager,
                  typereg::Reader const & reader,
                  codemaker::GeneratedTypeSet & generated,
                  rtl::OString const & delegate,
                  rtl::OString const & indentation=rtl::OString(),
                  bool defaultvalue=false,
                  bool usepropertymixin=false);

void printConstructionMethods(std::ostream & o,
                              ProgramOptions const & options,
                              TypeManager const & manager,
                              typereg::Reader const & reader);

void printServiceMembers(std::ostream & o,
                         ProgramOptions const & options,
                         TypeManager const & manager,
                         typereg::Reader const & reader,
                         rtl::OString const & type,
                         rtl::OString const & delegate);

void printMapsToJavaType(std::ostream & o,
                         ProgramOptions const & options,
                         TypeManager const & manager,
                         codemaker::UnoType::Sort sort,
                         RTTypeClass typeClass,
                         rtl::OString const & name, sal_Int32 rank,
                         std::vector< rtl::OString > const & arguments,
                         const char * javaTypeSort);

void generateDocumentation(std::ostream & o,
                           ProgramOptions const & options,
                           TypeManager const & manager,
                           rtl::OString const & type,
                           rtl::OString const & delegate);

void generateSkeleton(ProgramOptions const & options, TypeManager const & manager, std::vector< rtl::OString > const & types, rtl::OString const & delegate);

} }

#endif // _UNO_DEVTOOLS_SKELETONJAVA_HXX_

<commit_msg>INTEGRATION: CWS jsc3 (1.3.6); FILE MERGED 2006/01/20 13:08:41 jsc 1.3.6.1: #i56247# unify include guards<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: skeletonjava.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-15 09:20:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX
#define INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX

#include <fstream>

#ifndef INCLUDED_CODEMAKER_GENERATEDTYPESET_HXX
#include "codemaker/generatedtypeset.hxx"
#endif
#ifndef INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX
#include "skeletoncommon.hxx"
#endif

namespace skeletonmaker { namespace java {

void printType(std::ostream & o,
               ProgramOptions const & options, TypeManager const & manager,
               codemaker::UnoType::Sort sort, RTTypeClass typeClass,
               rtl::OString const & name, sal_Int32 rank,
               std::vector< rtl::OString > const & arguments,
               bool referenceType, bool defaultvalue=false);

void printType(std::ostream & o,
               ProgramOptions const & options, TypeManager const & manager,
               rtl::OString const & type, bool referenceType,
               bool defaultvalue=false);

bool printConstructorParameters(std::ostream & o,
                                ProgramOptions const & options,
                                TypeManager const & manager,
                                typereg::Reader const & reader,
                                typereg::Reader const & outerReader,
                                std::vector< rtl::OString > const & arguments);

void printConstructor(std::ostream & o,
                      ProgramOptions const & options, TypeManager const & manager,
                      typereg::Reader const & reader,
                      std::vector< rtl::OString > const & arguments);

void printMethodParameters(std::ostream & o,
                           ProgramOptions const & options,
                           TypeManager const & manager,
                           typereg::Reader const & reader,
                           sal_uInt16 method, bool previous,
                           bool withtype,
                           bool shortname=false);

void printExceptionSpecification(std::ostream & o,
                                 ProgramOptions const & options,
                                 TypeManager const & manager,
                                 typereg::Reader const & reader,
                                 sal_uInt16 method);

void printMethods(std::ostream & o,
                  ProgramOptions const & options, TypeManager const & manager,
                  typereg::Reader const & reader,
                  codemaker::GeneratedTypeSet & generated,
                  rtl::OString const & delegate,
                  rtl::OString const & indentation=rtl::OString(),
                  bool defaultvalue=false,
                  bool usepropertymixin=false);

void printConstructionMethods(std::ostream & o,
                              ProgramOptions const & options,
                              TypeManager const & manager,
                              typereg::Reader const & reader);

void printServiceMembers(std::ostream & o,
                         ProgramOptions const & options,
                         TypeManager const & manager,
                         typereg::Reader const & reader,
                         rtl::OString const & type,
                         rtl::OString const & delegate);

void printMapsToJavaType(std::ostream & o,
                         ProgramOptions const & options,
                         TypeManager const & manager,
                         codemaker::UnoType::Sort sort,
                         RTTypeClass typeClass,
                         rtl::OString const & name, sal_Int32 rank,
                         std::vector< rtl::OString > const & arguments,
                         const char * javaTypeSort);

void generateDocumentation(std::ostream & o,
                           ProgramOptions const & options,
                           TypeManager const & manager,
                           rtl::OString const & type,
                           rtl::OString const & delegate);

void generateSkeleton(ProgramOptions const & options, TypeManager const & manager, std::vector< rtl::OString > const & types, rtl::OString const & delegate);

} }

#endif // INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX

<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// *       Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// *       Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------
//
//	Run a set of CTL transforms to generate a color lookup table.
//
//-----------------------------------------------------------------------------

#include <ctlToLut.h>

#if HAVE_CTL_INTERPRETER

    #include <ImfCtlApplyTransforms.h>
    #include <CtlSimdInterpreter.h>
    #include <ImfStandardAttributes.h>
    #include <ImfHeader.h>
    #include <stdlib.h>
    #include <ImfFrameBuffer.h>
    #include <cassert>
    #include <iostream>

    using namespace std;
    using namespace Ctl;
    using namespace Imf;
    using namespace Imath;

#else

    #include <ImfStandardAttributes.h>
    #include <ImfHeader.h>
    #include <stdlib.h>
    #include <cassert>
    #include <iostream>

    using namespace std;
    using namespace Imf;
    using namespace Imath;

#endif

#define WARNING(message) (cerr << "Warning: " << message << endl)

float
displayVideoGamma ()
{
    //
    // Get the display's video gamma from an environment variable.
    // If this fails, use a default value (1/2.2).
    //

    const char gammaEnv[] = "EXR_DISPLAY_VIDEO_GAMMA";
    float g = 2.2f;

    if (const char *gamma = getenv (gammaEnv))
    {
	float tmp;
	int n = sscanf (gamma, " %f", &tmp);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " << gammaEnv << "; "
		     "using default value (" << g << ").");
	else if (tmp < 1.f)
	    WARNING ("Display video gamma, specified in environment "
		     "variable " << gammaEnv << " is out of range; "
		     "using default value (" << g << ").");
	else
	    g = tmp;
    }
    else
    {
	    WARNING ("Environment variable " << gammaEnv << " is not set; "
		     "using default value (" << g << ").");
    }

    return 1.f / g;
}

#if HAVE_CTL_INTERPRETER

namespace {

void
initializeEnvHeader (Header &envHeader)
{
    //
    // Initialize the "environment header" for the CTL
    // transforms by adding displayChromaticities,
    // displayWhiteLuminance and displaySurroundLuminance
    // attributes.
    //

    //
    // Get the chromaticities of the display's primaries and
    // white point from an environment variable.  If this fails,
    // assume chromaticities according to Rec. ITU-R BT.709.
    //

    static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
    Chromaticities c;  // default-initialized according to Rec. 709

    if (const char *chromaticities = getenv (chromaticitiesEnv))
    {
	Chromaticities tmp;

	int n = sscanf (chromaticities,
			" red %f %f green %f %f blue %f %f white %f %f",
			&tmp.red.x, &tmp.red.y,
			&tmp.green.x, &tmp.green.y,
			&tmp.blue.x, &tmp.blue.y,
			&tmp.white.x, &tmp.white.y);

	if (n == 8)
	    c = tmp;
	else
	    WARNING ("Cannot parse environment variable " <<
		     chromaticitiesEnv << "; using default value "
		     "(chromaticities according to Rec. ITU-R BT.709).");
    }
    else
    {
	WARNING ("Environment variable " << chromaticitiesEnv << " is "
		 "not set; using default value (chromaticities according "
		 "to Rec. ITU-R BT.709).");
    }

    envHeader.insert ("displayChromaticities", ChromaticitiesAttribute (c));

    //
    // Get the display's white luminance from an environment variable.
    // If this fails, assume 120 candelas per square meter.
    // (Screen aim luminance according to SMPTE RP 166.)
    //

    static const char whiteLuminanceEnv[] = "CTL_DISPLAY_WHITE_LUMINANCE";
    static const float whiteLuminanceDefault = 120.0;
    float wl = whiteLuminanceDefault;

    if (const char *whiteLuminance = getenv (whiteLuminanceEnv))
    {
	int n = sscanf (whiteLuminance, " %f", &wl);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " <<
		     whiteLuminanceEnv << "; using default value "
		     "(" << wl << " candelas per square meter).");
    }
    else
    {
	    WARNING ("Environment variable " << whiteLuminanceEnv << "  is "
		     "is not set; using default value (" << wl << " candelas "
		     "per square meter).");
    }

    envHeader.insert ("displayWhiteLuminance", FloatAttribute (wl));

    //
    // Get the display's surround luminance from an environment variable.
    // If this fails, assume 10% of the display's white luminance.
    // (Recommended setup according to SMPTE RP 166.)
    //

    static const char surroundLuminanceEnv[] = "CTL_DISPLAY_SURROUND_LUMINANCE";
    float sl = wl * 0.1f;

    if (const char *surroundLuminance = getenv (surroundLuminanceEnv))
    {
	int n = sscanf (surroundLuminance, " %f", &sl);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " <<
		     surroundLuminanceEnv << "; using default value "
		     "(" << sl << " candelas per square meter).");
    }
    else
    {
	    WARNING ("Environment variable " << surroundLuminanceEnv << "  is "
		     "is not set; using default value (" << sl << " candelas "
		     "per square meter).");
    }

    envHeader.insert ("displaySurroundLuminance", FloatAttribute (sl));
}

string
displayTransformName ()
{
    //
    // Get the name of the display transform from an environment
    // variable.  If this fails, use a default name.
    //

    static const char displayTransformEnv[] = "CTL_DISPLAY_TRANSFORM";
    static const char displayTransformDefault[] = "transform_display_video";
    const char *displayTransform = getenv (displayTransformEnv);

    if (!displayTransform)
    {
	displayTransform = displayTransformDefault;

	WARNING ("Environment variable " << displayTransformEnv << " "
		 "is not set; using default value "
		 "(\"" << displayTransform << "\").");
    }

    return displayTransform;
}

} // namespace

void
ctlToLut (vector<string> transformNames,
	  Header inHeader,
	  size_t lutSize,
	  const half pixelValues[/*lutSize*/],
	  half lut[/*lutSize*/])
{
    //
    // If we do not have an explicit set of transform names
    // then find suitable look modification, rendering and
    // display transforms.
    //

    if (transformNames.empty())
    {
	if (hasLookModTransform (inHeader))
	    transformNames.push_back (lookModTransform (inHeader));

	if (hasRenderingTransform (inHeader))
	    transformNames.push_back (renderingTransform (inHeader));
	else
	    transformNames.push_back ("transform_RRT");

	transformNames.push_back (displayTransformName());
    }

    //
    // Initialize an input and an environment header:
    // Make sure that the headers contain information about the primaries
    // and the white point of the image files an the display, and about
    // the display's white luminance and surround luminance.
    //

    Header envHeader;
    Header outHeader;

    if (!hasChromaticities (inHeader))
	addChromaticities (inHeader, Chromaticities());

    if (!hasAdoptedNeutral (inHeader))
	addAdoptedNeutral (inHeader, chromaticities(inHeader).white);

    initializeEnvHeader (envHeader);

    //
    // Set up input and output FrameBuffer objects for the CTL transforms.
    //

    assert (lutSize % 4 == 0);

    FrameBuffer inFb;

    inFb.insert ("R",
		 Slice (HALF,				// type
		        (char *)pixelValues,		// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    inFb.insert ("G",
		 Slice (HALF,				// type
			(char *)(pixelValues + 1),	// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    inFb.insert ("B",
		 Slice (HALF,				// type
			(char *)(pixelValues + 2),	// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    FrameBuffer outFb;

    outFb.insert ("R_display",
		  Slice (HALF,				// type
			 (char *)lut,			// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    outFb.insert ("G_display",
		  Slice (HALF,				// type
			 (char *)(lut + 1),		// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    outFb.insert ("B_display",
		  Slice (HALF,				// type
			 (char *)(lut + 2),		// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    //
    // Run the CTL transforms.
    //

    SimdInterpreter interpreter;

    #ifdef CTL_MODULE_BASE_PATH

	//
	// The configuration scripts has defined a default
	// location for CTL modules.  Include this location
	// in the CTL module search path.
	//

	vector<string> paths = interpreter.modulePaths();
	paths.push_back (CTL_MODULE_BASE_PATH);
	interpreter.setModulePaths (paths);

    #endif

    ImfCtl::applyTransforms (interpreter,
			     transformNames,
			     Box2i (V2i (0, 0), V2i (lutSize / 4 - 1, 0)),
			     envHeader,
			     inHeader,
			     inFb,
			     outHeader,
			     outFb);
}

#else

#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <cassert>
#include <iostream>

using namespace std;
using namespace Imf;
using namespace Imath;

#define WARNING(message) (cerr << "Warning: " << message << endl)

void
ctlToLut (vector<string> transformNames,
	  Header inHeader,
	  size_t lutSize,
	  const half pixelValues[/*lutSize*/],
	  half lut[/*lutSize*/])
{
    //
    // This program has been compiled without CTL support.
    //
    // Our fallback solution is to build a lookup table that
    // performs a coordinate transform from the primaries and
    // white point of the input files to the primaries and
    // white point of the display.
    //

    //
    // Get the input file chromaticities
    //

    Chromaticities fileChroma;

    if (hasChromaticities (inHeader))
	fileChroma = chromaticities (inHeader);

    //
    // Get the display chromaticities
    //

    static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
    Chromaticities displayChroma;

    if (const char *chromaticities = getenv (chromaticitiesEnv))
    {
	Chromaticities tmp;

	int n = sscanf (chromaticities,
			" red %f %f green %f %f blue %f %f white %f %f",
			&tmp.red.x, &tmp.red.y,
			&tmp.green.x, &tmp.green.y,
			&tmp.blue.x, &tmp.blue.y,
			&tmp.white.x, &tmp.white.y);

	if (n == 8)
	    displayChroma = tmp;
	else
	    WARNING ("Cannot parse environment variable " <<
		     chromaticitiesEnv << "; using default value "
		     "(chromaticities according to Rec. ITU-R BT.709).");
    }
    else
    {
	WARNING ("Environment variable " << chromaticitiesEnv << " is "
		 "not set; using default value (chromaticities according "
		 "to Rec. ITU-R BT.709).");
    }

    //
    // Do the coordinate transform
    //

    M44f M = RGBtoXYZ (fileChroma, 1) * XYZtoRGB (displayChroma, 1);

    assert (lutSize % 4 == 0);

    for (int i = 0; i < lutSize; i += 4)
    {
	V3f rgb (pixelValues[i], pixelValues[i + 1], pixelValues[i + 2]);
	rgb = rgb * M;

	lut[i + 0] = rgb[0];
	lut[i + 1] = rgb[1];
	lut[i + 2] = rgb[2];
	lut[i + 3] = 0;
    }
}

#endif
<commit_msg>Fix for gcc-4.4 - Cg enabled build<commit_after>///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// *       Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// *       Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// *       Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------
//
//	Run a set of CTL transforms to generate a color lookup table.
//
//-----------------------------------------------------------------------------

#include <stdio.h>
#include <ctlToLut.h>

#if HAVE_CTL_INTERPRETER

    #include <ImfCtlApplyTransforms.h>
    #include <CtlSimdInterpreter.h>
    #include <ImfStandardAttributes.h>
    #include <ImfHeader.h>
    #include <stdlib.h>
    #include <ImfFrameBuffer.h>
    #include <cassert>
    #include <iostream>

    using namespace std;
    using namespace Ctl;
    using namespace Imf;
    using namespace Imath;

#else

    #include <ImfStandardAttributes.h>
    #include <ImfHeader.h>
    #include <stdlib.h>
    #include <cassert>
    #include <iostream>

    using namespace std;
    using namespace Imf;
    using namespace Imath;

#endif

#define WARNING(message) (cerr << "Warning: " << message << endl)

float
displayVideoGamma ()
{
    //
    // Get the display's video gamma from an environment variable.
    // If this fails, use a default value (1/2.2).
    //

    const char gammaEnv[] = "EXR_DISPLAY_VIDEO_GAMMA";
    float g = 2.2f;

    if (const char *gamma = getenv (gammaEnv))
    {
	float tmp;
	int n = sscanf (gamma, " %f", &tmp);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " << gammaEnv << "; "
		     "using default value (" << g << ").");
	else if (tmp < 1.f)
	    WARNING ("Display video gamma, specified in environment "
		     "variable " << gammaEnv << " is out of range; "
		     "using default value (" << g << ").");
	else
	    g = tmp;
    }
    else
    {
	    WARNING ("Environment variable " << gammaEnv << " is not set; "
		     "using default value (" << g << ").");
    }

    return 1.f / g;
}

#if HAVE_CTL_INTERPRETER

namespace {

void
initializeEnvHeader (Header &envHeader)
{
    //
    // Initialize the "environment header" for the CTL
    // transforms by adding displayChromaticities,
    // displayWhiteLuminance and displaySurroundLuminance
    // attributes.
    //

    //
    // Get the chromaticities of the display's primaries and
    // white point from an environment variable.  If this fails,
    // assume chromaticities according to Rec. ITU-R BT.709.
    //

    static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
    Chromaticities c;  // default-initialized according to Rec. 709

    if (const char *chromaticities = getenv (chromaticitiesEnv))
    {
	Chromaticities tmp;

	int n = sscanf (chromaticities,
			" red %f %f green %f %f blue %f %f white %f %f",
			&tmp.red.x, &tmp.red.y,
			&tmp.green.x, &tmp.green.y,
			&tmp.blue.x, &tmp.blue.y,
			&tmp.white.x, &tmp.white.y);

	if (n == 8)
	    c = tmp;
	else
	    WARNING ("Cannot parse environment variable " <<
		     chromaticitiesEnv << "; using default value "
		     "(chromaticities according to Rec. ITU-R BT.709).");
    }
    else
    {
	WARNING ("Environment variable " << chromaticitiesEnv << " is "
		 "not set; using default value (chromaticities according "
		 "to Rec. ITU-R BT.709).");
    }

    envHeader.insert ("displayChromaticities", ChromaticitiesAttribute (c));

    //
    // Get the display's white luminance from an environment variable.
    // If this fails, assume 120 candelas per square meter.
    // (Screen aim luminance according to SMPTE RP 166.)
    //

    static const char whiteLuminanceEnv[] = "CTL_DISPLAY_WHITE_LUMINANCE";
    static const float whiteLuminanceDefault = 120.0;
    float wl = whiteLuminanceDefault;

    if (const char *whiteLuminance = getenv (whiteLuminanceEnv))
    {
	int n = sscanf (whiteLuminance, " %f", &wl);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " <<
		     whiteLuminanceEnv << "; using default value "
		     "(" << wl << " candelas per square meter).");
    }
    else
    {
	    WARNING ("Environment variable " << whiteLuminanceEnv << "  is "
		     "is not set; using default value (" << wl << " candelas "
		     "per square meter).");
    }

    envHeader.insert ("displayWhiteLuminance", FloatAttribute (wl));

    //
    // Get the display's surround luminance from an environment variable.
    // If this fails, assume 10% of the display's white luminance.
    // (Recommended setup according to SMPTE RP 166.)
    //

    static const char surroundLuminanceEnv[] = "CTL_DISPLAY_SURROUND_LUMINANCE";
    float sl = wl * 0.1f;

    if (const char *surroundLuminance = getenv (surroundLuminanceEnv))
    {
	int n = sscanf (surroundLuminance, " %f", &sl);

	if (n != 1)
	    WARNING ("Cannot parse environment variable " <<
		     surroundLuminanceEnv << "; using default value "
		     "(" << sl << " candelas per square meter).");
    }
    else
    {
	    WARNING ("Environment variable " << surroundLuminanceEnv << "  is "
		     "is not set; using default value (" << sl << " candelas "
		     "per square meter).");
    }

    envHeader.insert ("displaySurroundLuminance", FloatAttribute (sl));
}

string
displayTransformName ()
{
    //
    // Get the name of the display transform from an environment
    // variable.  If this fails, use a default name.
    //

    static const char displayTransformEnv[] = "CTL_DISPLAY_TRANSFORM";
    static const char displayTransformDefault[] = "transform_display_video";
    const char *displayTransform = getenv (displayTransformEnv);

    if (!displayTransform)
    {
	displayTransform = displayTransformDefault;

	WARNING ("Environment variable " << displayTransformEnv << " "
		 "is not set; using default value "
		 "(\"" << displayTransform << "\").");
    }

    return displayTransform;
}

} // namespace

void
ctlToLut (vector<string> transformNames,
	  Header inHeader,
	  size_t lutSize,
	  const half pixelValues[/*lutSize*/],
	  half lut[/*lutSize*/])
{
    //
    // If we do not have an explicit set of transform names
    // then find suitable look modification, rendering and
    // display transforms.
    //

    if (transformNames.empty())
    {
	if (hasLookModTransform (inHeader))
	    transformNames.push_back (lookModTransform (inHeader));

	if (hasRenderingTransform (inHeader))
	    transformNames.push_back (renderingTransform (inHeader));
	else
	    transformNames.push_back ("transform_RRT");

	transformNames.push_back (displayTransformName());
    }

    //
    // Initialize an input and an environment header:
    // Make sure that the headers contain information about the primaries
    // and the white point of the image files an the display, and about
    // the display's white luminance and surround luminance.
    //

    Header envHeader;
    Header outHeader;

    if (!hasChromaticities (inHeader))
	addChromaticities (inHeader, Chromaticities());

    if (!hasAdoptedNeutral (inHeader))
	addAdoptedNeutral (inHeader, chromaticities(inHeader).white);

    initializeEnvHeader (envHeader);

    //
    // Set up input and output FrameBuffer objects for the CTL transforms.
    //

    assert (lutSize % 4 == 0);

    FrameBuffer inFb;

    inFb.insert ("R",
		 Slice (HALF,				// type
		        (char *)pixelValues,		// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    inFb.insert ("G",
		 Slice (HALF,				// type
			(char *)(pixelValues + 1),	// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    inFb.insert ("B",
		 Slice (HALF,				// type
			(char *)(pixelValues + 2),	// base
			4 * sizeof (half),		// xStride
			0));				// yStride

    FrameBuffer outFb;

    outFb.insert ("R_display",
		  Slice (HALF,				// type
			 (char *)lut,			// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    outFb.insert ("G_display",
		  Slice (HALF,				// type
			 (char *)(lut + 1),		// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    outFb.insert ("B_display",
		  Slice (HALF,				// type
			 (char *)(lut + 2),		// base
			 4 * sizeof (half),		// xStride
			 0));				// yStride

    //
    // Run the CTL transforms.
    //

    SimdInterpreter interpreter;

    #ifdef CTL_MODULE_BASE_PATH

	//
	// The configuration scripts has defined a default
	// location for CTL modules.  Include this location
	// in the CTL module search path.
	//

	vector<string> paths = interpreter.modulePaths();
	paths.push_back (CTL_MODULE_BASE_PATH);
	interpreter.setModulePaths (paths);

    #endif

    ImfCtl::applyTransforms (interpreter,
			     transformNames,
			     Box2i (V2i (0, 0), V2i (lutSize / 4 - 1, 0)),
			     envHeader,
			     inHeader,
			     inFb,
			     outHeader,
			     outFb);
}

#else

#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <cassert>
#include <iostream>

using namespace std;
using namespace Imf;
using namespace Imath;

#define WARNING(message) (cerr << "Warning: " << message << endl)

void
ctlToLut (vector<string> transformNames,
	  Header inHeader,
	  size_t lutSize,
	  const half pixelValues[/*lutSize*/],
	  half lut[/*lutSize*/])
{
    //
    // This program has been compiled without CTL support.
    //
    // Our fallback solution is to build a lookup table that
    // performs a coordinate transform from the primaries and
    // white point of the input files to the primaries and
    // white point of the display.
    //

    //
    // Get the input file chromaticities
    //

    Chromaticities fileChroma;

    if (hasChromaticities (inHeader))
	fileChroma = chromaticities (inHeader);

    //
    // Get the display chromaticities
    //

    static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
    Chromaticities displayChroma;

    if (const char *chromaticities = getenv (chromaticitiesEnv))
    {
	Chromaticities tmp;

	int n = sscanf (chromaticities,
			" red %f %f green %f %f blue %f %f white %f %f",
			&tmp.red.x, &tmp.red.y,
			&tmp.green.x, &tmp.green.y,
			&tmp.blue.x, &tmp.blue.y,
			&tmp.white.x, &tmp.white.y);

	if (n == 8)
	    displayChroma = tmp;
	else
	    WARNING ("Cannot parse environment variable " <<
		     chromaticitiesEnv << "; using default value "
		     "(chromaticities according to Rec. ITU-R BT.709).");
    }
    else
    {
	WARNING ("Environment variable " << chromaticitiesEnv << " is "
		 "not set; using default value (chromaticities according "
		 "to Rec. ITU-R BT.709).");
    }

    //
    // Do the coordinate transform
    //

    M44f M = RGBtoXYZ (fileChroma, 1) * XYZtoRGB (displayChroma, 1);

    assert (lutSize % 4 == 0);

    for (int i = 0; i < lutSize; i += 4)
    {
	V3f rgb (pixelValues[i], pixelValues[i + 1], pixelValues[i + 2]);
	rgb = rgb * M;

	lut[i + 0] = rgb[0];
	lut[i + 1] = rgb[1];
	lut[i + 2] = rgb[2];
	lut[i + 3] = 0;
    }
}

#endif
<|endoftext|>