<commit_before>/*---------------------------------------------------------------------------*\
 *                                OpenSG                                     *
 *                                                                           *
 *                                                                           *
 *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
 *                                                                           *
 *                            www.opensg.org                                 *
 *                                                                           *
 *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
 *                                                                           *
\*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*\
 *                                License                                    *
 *                                                                           *
 * This library is free software; you can redistribute it and/or modify it   *
 * under the terms of the GNU Library General Public License as published    *
 * by the Free Software Foundation, version 2.                               *
 *                                                                           *
 * 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         *
 * Library General Public License for more details.                          *
 *                                                                           *
 * You should have received a copy of the GNU Library General Public         *
 * License along with this library; if not, write to the Free Software       *
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
 *                                                                           *
\*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*\
 *                                Changes                                    *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
\*---------------------------------------------------------------------------*/

#define GL_GLEXT_PROTOTYPES

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <cstdlib>
#include <cstdio>

#include <boost/bind.hpp>

#include "OSGConfig.h"

#include <OSGGL.h>
#include <OSGGLU.h>
#include <OSGGLEXT.h>
#include <OSGImage.h>

#include "OSGDrawActionBase.h"
#include "OSGDrawEnv.h"

#include "OSGTextureObjRefChunk.h"

//#define OSG_DUMP_TEX

OSG_USING_NAMESPACE

// Documentation for this class is emited in the
// OSGTextureObjRefChunkBase.cpp file.
// To modify it, please change the .fcd file (OSGTextureObjRefChunk.fcd) and
// regenerate the base file.

/***************************************************************************\
 *                           Class variables                               *
\***************************************************************************/

/***************************************************************************\
 *                           Class methods                                 *
\***************************************************************************/

/*-------------------------------------------------------------------------*\
 -  private                                                                -
\*-------------------------------------------------------------------------*/

void TextureObjRefChunk::initMethod(InitPhase ePhase)
{
    Inherited::initMethod(ePhase);
}

/***************************************************************************\
 *                           Instance methods                              *
\***************************************************************************/

/*-------------------------------------------------------------------------*\
 -  private                                                                 -
\*-------------------------------------------------------------------------*/

/*------------- constructors & destructors --------------------------------*/

TextureObjRefChunk::TextureObjRefChunk(void) :
    Inherited()
{
}

TextureObjRefChunk::TextureObjRefChunk(const TextureObjRefChunk &source) :
    Inherited(source)
{
}

TextureObjRefChunk::~TextureObjRefChunk(void)
{
}

/*------------------------- Chunk Class Access ---------------------------*/

/*------------------------------- Sync -----------------------------------*/

/*! React to field changes.
    Note: this function also handles CubeTexture changes, make sure to keep
    it consistent with the cubeTexture specifics
*/

void TextureObjRefChunk::changed(BitVector whichField, UInt32 origin)
{
    Inherited::changed(whichField, origin);
}

bool TextureObjRefChunk::isTransparent(void) const
{
    // Even if the texture has alpha, the Blending is makes the sorting
    // important, thus textures per se are not transparent
    return false;
}

/*----------------------------- onCreate --------------------------------*/

void TextureObjRefChunk::onCreate(const TextureObjRefChunk *source)
{
    Inherited::onCreate(source);
}

void TextureObjRefChunk::onCreateAspect(const TextureObjRefChunk *createAspect,
                                        const TextureObjRefChunk *source      )
{
    Inherited::onCreateAspect(createAspect, source);
}

/*------------------------------ Output ----------------------------------*/

void TextureObjRefChunk::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
                              const BitVector OSG_CHECK_ARG(bvFlags )) const
{
    SLOG << "Dump TextureObjRefChunk NI" << std::endl;
}

/*------------------------------ State ------------------------------------*/

void TextureObjRefChunk::activate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glBindTexture(this->getTarget(),
                  this->getGLId  ());

    pEnv->setActiveTexTarget(idx, this->getTarget());

    glEnable(this->getTarget());
}

void TextureObjRefChunk::changeFrom(DrawEnv    *pEnv,
                                    StateChunk *old   ,
                                    UInt32      idx )
{
    // change from me to me?
    // this assumes I haven't changed in the meantime.
    // is that a valid assumption?
    if(old == this)
        return;

    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glBindTexture(this->getTarget(),
                  this->getGLId  ());

    pEnv->setActiveTexTarget(idx, this->getTarget());

    glEnable(this->getTarget());
}

void TextureObjRefChunk::deactivate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glDisable(this->getTarget());

    pEnv->setActiveTexTarget(idx, GL_NONE);
}

/*-------------------------- Comparison -----------------------------------*/

Real32 TextureObjRefChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
{
    return 0;
}

bool TextureObjRefChunk::operator < (const StateChunk &other) const
{
    return this < &other;
}

bool TextureObjRefChunk::operator == (const StateChunk &other) const
{
    bool returnValue = false;

    return returnValue;
}

bool TextureObjRefChunk::operator != (const StateChunk &other) const
{
    return ! (*this == other);
}

<commit_msg>fixed : wrong-glid-mapping<commit_after>/*---------------------------------------------------------------------------*\
 *                                OpenSG                                     *
 *                                                                           *
 *                                                                           *
 *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
 *                                                                           *
 *                            www.opensg.org                                 *
 *                                                                           *
 *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
 *                                                                           *
\*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*\
 *                                License                                    *
 *                                                                           *
 * This library is free software; you can redistribute it and/or modify it   *
 * under the terms of the GNU Library General Public License as published    *
 * by the Free Software Foundation, version 2.                               *
 *                                                                           *
 * 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         *
 * Library General Public License for more details.                          *
 *                                                                           *
 * You should have received a copy of the GNU Library General Public         *
 * License along with this library; if not, write to the Free Software       *
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
 *                                                                           *
\*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*\
 *                                Changes                                    *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
 *                                                                           *
\*---------------------------------------------------------------------------*/

#define GL_GLEXT_PROTOTYPES

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <cstdlib>
#include <cstdio>

#include <boost/bind.hpp>

#include "OSGConfig.h"

#include <OSGGL.h>
#include <OSGGLU.h>
#include <OSGGLEXT.h>
#include <OSGImage.h>

#include "OSGDrawActionBase.h"
#include "OSGDrawEnv.h"

#include "OSGTextureObjRefChunk.h"

//#define OSG_DUMP_TEX

OSG_USING_NAMESPACE

// Documentation for this class is emited in the
// OSGTextureObjRefChunkBase.cpp file.
// To modify it, please change the .fcd file (OSGTextureObjRefChunk.fcd) and
// regenerate the base file.

/***************************************************************************\
 *                           Class variables                               *
\***************************************************************************/

/***************************************************************************\
 *                           Class methods                                 *
\***************************************************************************/

/*-------------------------------------------------------------------------*\
 -  private                                                                -
\*-------------------------------------------------------------------------*/

void TextureObjRefChunk::initMethod(InitPhase ePhase)
{
    Inherited::initMethod(ePhase);
}

/***************************************************************************\
 *                           Instance methods                              *
\***************************************************************************/

/*-------------------------------------------------------------------------*\
 -  private                                                                 -
\*-------------------------------------------------------------------------*/

/*------------- constructors & destructors --------------------------------*/

TextureObjRefChunk::TextureObjRefChunk(void) :
    Inherited()
{
}

TextureObjRefChunk::TextureObjRefChunk(const TextureObjRefChunk &source) :
    Inherited(source)
{
}

TextureObjRefChunk::~TextureObjRefChunk(void)
{
}

/*------------------------- Chunk Class Access ---------------------------*/

/*------------------------------- Sync -----------------------------------*/

/*! React to field changes.
    Note: this function also handles CubeTexture changes, make sure to keep
    it consistent with the cubeTexture specifics
*/

void TextureObjRefChunk::changed(BitVector whichField, UInt32 origin)
{
    Inherited::changed(whichField, origin);
}

bool TextureObjRefChunk::isTransparent(void) const
{
    // Even if the texture has alpha, the Blending is makes the sorting
    // important, thus textures per se are not transparent
    return false;
}

/*----------------------------- onCreate --------------------------------*/

void TextureObjRefChunk::onCreate(const TextureObjRefChunk *source)
{
    Inherited::onCreate(source);
}

void TextureObjRefChunk::onCreateAspect(const TextureObjRefChunk *createAspect,
                                        const TextureObjRefChunk *source      )
{
    Inherited::onCreateAspect(createAspect, source);
}

/*------------------------------ Output ----------------------------------*/

void TextureObjRefChunk::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
                              const BitVector OSG_CHECK_ARG(bvFlags )) const
{
    SLOG << "Dump TextureObjRefChunk NI" << std::endl;
}

/*------------------------------ State ------------------------------------*/

void TextureObjRefChunk::activate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glBindTexture(this->getTarget(),
                  pWin->getGLObjectId(this->getGLId()));

    pEnv->setActiveTexTarget(idx, this->getTarget());

    glEnable(this->getTarget());
}

void TextureObjRefChunk::changeFrom(DrawEnv    *pEnv,
                                    StateChunk *old   ,
                                    UInt32      idx )
{
    // change from me to me?
    // this assumes I haven't changed in the meantime.
    // is that a valid assumption?
    if(old == this)
        return;

    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glBindTexture(this->getTarget(),
                  pWin->getGLObjectId(this->getGLId()));

    pEnv->setActiveTexTarget(idx, this->getTarget());

    glEnable(this->getTarget());
}

void TextureObjRefChunk::deactivate(DrawEnv *pEnv, UInt32 idx)
{
    Window *pWin = pEnv->getWindow();

    if(activateTexture(pWin, idx))
        return; // trying to access too many textures

    glDisable(this->getTarget());

    pEnv->setActiveTexTarget(idx, GL_NONE);
}

/*-------------------------- Comparison -----------------------------------*/

Real32 TextureObjRefChunk::switchCost(StateChunk *OSG_CHECK_ARG(chunk))
{
    return 0;
}

bool TextureObjRefChunk::operator < (const StateChunk &other) const
{
    return this < &other;
}

bool TextureObjRefChunk::operator == (const StateChunk &other) const
{
    bool returnValue = false;

    return returnValue;
}

bool TextureObjRefChunk::operator != (const StateChunk &other) const
{
    return ! (*this == other);
}

<|endoftext|>


<commit_before><commit_msg>compilo fixes<commit_after><|endoftext|>


<commit_before>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "ast.h"
#include "glsl_types.h"
#include "ir.h"

ir_rvalue *
_mesa_ast_array_index_to_hir(void *mem_ctx,
			     struct _mesa_glsl_parse_state *state,
			     ir_rvalue *array, ir_rvalue *idx,
			     YYLTYPE &loc, YYLTYPE &idx_loc,
			     bool error_emitted)
{
   ir_rvalue *result = new(mem_ctx) ir_dereference_array(array, idx);

   if (error_emitted)
      return result;

   if (!array->type->is_array()
       && !array->type->is_matrix()
       && !array->type->is_vector()) {
      _mesa_glsl_error(& idx_loc, state,
		       "cannot dereference non-array / non-matrix / "
		       "non-vector");
      result->type = glsl_type::error_type;
   }

   if (!idx->type->is_integer()) {
      _mesa_glsl_error(& idx_loc, state, "array index must be integer type");
   } else if (!idx->type->is_scalar()) {
      _mesa_glsl_error(& idx_loc, state, "array index must be scalar");
   }

   /* If the array index is a constant expression and the array has a
    * declared size, ensure that the access is in-bounds.  If the array
    * index is not a constant expression, ensure that the array has a
    * declared size.
    */
   ir_constant *const const_index = idx->constant_expression_value();
   if (const_index != NULL) {
      const int idx = const_index->value.i[0];
      const char *type_name = "error";
      unsigned bound = 0;

      /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
       *
       *    "It is illegal to declare an array with a size, and then
       *    later (in the same shader) index the same array with an
       *    integral constant expression greater than or equal to the
       *    declared size. It is also illegal to index an array with a
       *    negative constant expression."
       */
      if (array->type->is_matrix()) {
	 if (array->type->row_type()->vector_elements <= idx) {
	    type_name = "matrix";
	    bound = array->type->row_type()->vector_elements;
	 }
      } else if (array->type->is_vector()) {
	 if (array->type->vector_elements <= idx) {
	    type_name = "vector";
	    bound = array->type->vector_elements;
	 }
      } else {
	 /* glsl_type::array_size() returns 0 for non-array types.  This means
	  * that we don't need to verify that the type is an array before
	  * doing the bounds checking.
	  */
	 if ((array->type->array_size() > 0)
	     && (array->type->array_size() <= idx)) {
	    type_name = "array";
	    bound = array->type->array_size();
	 }
      }

      if (bound > 0) {
	 _mesa_glsl_error(& loc, state, "%s index must be < %u",
			  type_name, bound);
      } else if (idx < 0) {
	 _mesa_glsl_error(& loc, state, "%s index must be >= 0",
			  type_name);
      }

      if (array->type->is_array()) {
	 /* If the array is a variable dereference, it dereferences the
	  * whole array, by definition.  Use this to get the variable.
	  *
	  * FINISHME: Should some methods for getting / setting / testing
	  * FINISHME: array access limits be added to ir_dereference?
	  */
	 ir_variable *const v = array->whole_variable_referenced();
	 if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
	    v->max_array_access = idx;

	    /* Check whether this access will, as a side effect, implicitly
	     * cause the size of a built-in array to be too large.
	     */
	    check_builtin_array_max_size(v->name, idx+1, loc, state);
	 }
      }
   } else if (array->type->is_array()) {
      if (array->type->array_size() == 0) {
	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
      } else if (array->type->fields.array->is_interface()) {
	 /* Page 46 in section 4.3.7 of the OpenGL ES 3.00 spec says:
	  *
	  *     "All indexes used to index a uniform block array must be
	  *     constant integral expressions."
	  */
	 _mesa_glsl_error(&loc, state,
			  "uniform block array index must be constant");
      } else {
	 /* whole_variable_referenced can return NULL if the array is a
	  * member of a structure.  In this case it is safe to not update
	  * the max_array_access field because it is never used for fields
	  * of structures.
	  */
	 ir_variable *v = array->whole_variable_referenced();
	 if (v != NULL)
	    v->max_array_access = array->type->array_size() - 1;
      }

      /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
       *
       *    "Samplers aggregated into arrays within a shader (using square
       *    brackets [ ]) can only be indexed with integral constant
       *    expressions [...]."
       *
       * This restriction was added in GLSL 1.30.  Shaders using earlier
       * version of the language should not be rejected by the compiler
       * front-end for using this construct.  This allows useful things such
       * as using a loop counter as the index to an array of samplers.  If the
       * loop in unrolled, the code should compile correctly.  Instead, emit a
       * warning.
       */
      if (array->type->element_type()->is_sampler()) {
	 if (!state->is_version(130, 100)) {
	    if (state->es_shader) {
	       _mesa_glsl_warning(&loc, state,
				  "sampler arrays indexed with non-constant "
				  "expressions is optional in %s",
				  state->get_version_string());
	    } else {
	       _mesa_glsl_warning(&loc, state,
				  "sampler arrays indexed with non-constant "
				  "expressions will be forbidden in GLSL 1.30 "
				  "and later");
	    }
	 } else {
	    _mesa_glsl_error(&loc, state,
			     "sampler arrays indexed with non-constant "
			     "expressions is forbidden in GLSL 1.30 and "
			     "later");
	 }
      }
   }

   return result;
}
<commit_msg>glsl: Don't emit spurious errors for constant indexes of the wrong type<commit_after>/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "ast.h"
#include "glsl_types.h"
#include "ir.h"

ir_rvalue *
_mesa_ast_array_index_to_hir(void *mem_ctx,
			     struct _mesa_glsl_parse_state *state,
			     ir_rvalue *array, ir_rvalue *idx,
			     YYLTYPE &loc, YYLTYPE &idx_loc,
			     bool error_emitted)
{
   ir_rvalue *result = new(mem_ctx) ir_dereference_array(array, idx);

   if (error_emitted)
      return result;

   if (!array->type->is_array()
       && !array->type->is_matrix()
       && !array->type->is_vector()) {
      _mesa_glsl_error(& idx_loc, state,
		       "cannot dereference non-array / non-matrix / "
		       "non-vector");
      result->type = glsl_type::error_type;
   }

   if (!idx->type->is_integer()) {
      _mesa_glsl_error(& idx_loc, state, "array index must be integer type");
   } else if (!idx->type->is_scalar()) {
      _mesa_glsl_error(& idx_loc, state, "array index must be scalar");
   }

   /* If the array index is a constant expression and the array has a
    * declared size, ensure that the access is in-bounds.  If the array
    * index is not a constant expression, ensure that the array has a
    * declared size.
    */
   ir_constant *const const_index = idx->constant_expression_value();
   if (const_index != NULL && idx->type->is_integer()) {
      const int idx = const_index->value.i[0];
      const char *type_name = "error";
      unsigned bound = 0;

      /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
       *
       *    "It is illegal to declare an array with a size, and then
       *    later (in the same shader) index the same array with an
       *    integral constant expression greater than or equal to the
       *    declared size. It is also illegal to index an array with a
       *    negative constant expression."
       */
      if (array->type->is_matrix()) {
	 if (array->type->row_type()->vector_elements <= idx) {
	    type_name = "matrix";
	    bound = array->type->row_type()->vector_elements;
	 }
      } else if (array->type->is_vector()) {
	 if (array->type->vector_elements <= idx) {
	    type_name = "vector";
	    bound = array->type->vector_elements;
	 }
      } else {
	 /* glsl_type::array_size() returns 0 for non-array types.  This means
	  * that we don't need to verify that the type is an array before
	  * doing the bounds checking.
	  */
	 if ((array->type->array_size() > 0)
	     && (array->type->array_size() <= idx)) {
	    type_name = "array";
	    bound = array->type->array_size();
	 }
      }

      if (bound > 0) {
	 _mesa_glsl_error(& loc, state, "%s index must be < %u",
			  type_name, bound);
      } else if (idx < 0) {
	 _mesa_glsl_error(& loc, state, "%s index must be >= 0",
			  type_name);
      }

      if (array->type->is_array()) {
	 /* If the array is a variable dereference, it dereferences the
	  * whole array, by definition.  Use this to get the variable.
	  *
	  * FINISHME: Should some methods for getting / setting / testing
	  * FINISHME: array access limits be added to ir_dereference?
	  */
	 ir_variable *const v = array->whole_variable_referenced();
	 if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
	    v->max_array_access = idx;

	    /* Check whether this access will, as a side effect, implicitly
	     * cause the size of a built-in array to be too large.
	     */
	    check_builtin_array_max_size(v->name, idx+1, loc, state);
	 }
      }
   } else if (const_index == NULL && array->type->is_array()) {
      if (array->type->array_size() == 0) {
	 _mesa_glsl_error(&loc, state, "unsized array index must be constant");
      } else if (array->type->fields.array->is_interface()) {
	 /* Page 46 in section 4.3.7 of the OpenGL ES 3.00 spec says:
	  *
	  *     "All indexes used to index a uniform block array must be
	  *     constant integral expressions."
	  */
	 _mesa_glsl_error(&loc, state,
			  "uniform block array index must be constant");
      } else {
	 /* whole_variable_referenced can return NULL if the array is a
	  * member of a structure.  In this case it is safe to not update
	  * the max_array_access field because it is never used for fields
	  * of structures.
	  */
	 ir_variable *v = array->whole_variable_referenced();
	 if (v != NULL)
	    v->max_array_access = array->type->array_size() - 1;
      }

      /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
       *
       *    "Samplers aggregated into arrays within a shader (using square
       *    brackets [ ]) can only be indexed with integral constant
       *    expressions [...]."
       *
       * This restriction was added in GLSL 1.30.  Shaders using earlier
       * version of the language should not be rejected by the compiler
       * front-end for using this construct.  This allows useful things such
       * as using a loop counter as the index to an array of samplers.  If the
       * loop in unrolled, the code should compile correctly.  Instead, emit a
       * warning.
       */
      if (array->type->element_type()->is_sampler()) {
	 if (!state->is_version(130, 100)) {
	    if (state->es_shader) {
	       _mesa_glsl_warning(&loc, state,
				  "sampler arrays indexed with non-constant "
				  "expressions is optional in %s",
				  state->get_version_string());
	    } else {
	       _mesa_glsl_warning(&loc, state,
				  "sampler arrays indexed with non-constant "
				  "expressions will be forbidden in GLSL 1.30 "
				  "and later");
	    }
	 } else {
	    _mesa_glsl_error(&loc, state,
			     "sampler arrays indexed with non-constant "
			     "expressions is forbidden in GLSL 1.30 and "
			     "later");
	 }
      }
   }

   return result;
}
<|endoftext|>


<commit_before>//===-- driver.cpp - Swift Compiler Driver --------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the swift compiler driver.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Driver/Compilation.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/Job.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>

using namespace swift;
using namespace swift::driver;

std::string getExecutablePath(const char *FirstArg) {
  void *P = (void *)(intptr_t)getExecutablePath;
  return llvm::sys::fs::getMainExecutable(FirstArg, P);
}

extern int frontend_main(ArrayRef<const char *> Args, const char *Argv0,
                         void *MainAddr);
extern int transform_ir_main(ArrayRef<const char *> Args, const char *Argv0,
                             void *MainAddr);

int main(int argc_, const char **argv_) {
  // Print a stack trace if we signal out.
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc_, argv_);

  // Set up an object which will call llvm::llvm_shutdown() on exit.
  llvm::llvm_shutdown_obj Y;

  llvm::SmallVector<const char *, 256> argv;
  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
  llvm::error_code EC = llvm::sys::Process::GetArgumentVector(argv,
                      llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
  if (EC) {
    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
    return 1;
  }

  // Handle integrated tools.
  if (argv.size() > 1){
    StringRef FirstArg(argv[1]);
    if (FirstArg == "-frontend") {
      return frontend_main(llvm::makeArrayRef(argv.data()+2,
                                              argv.data()+argv.size()),
                           argv[0], (void *)(intptr_t)getExecutablePath);
    } else if (FirstArg == "-transform-ir") {
      return transform_ir_main(llvm::makeArrayRef(argv.data()+2,
                                                  argv.data()+argv.size()),
                               argv[0], (void *)(intptr_t)getExecutablePath);
    }
  }

  std::string Path = getExecutablePath(argv[0]);

  PrintingDiagnosticConsumer PDC;

  SourceManager SM;
  DiagnosticEngine Diags(SM);
  Diags.addConsumer(PDC);

  Driver TheDriver(Path, Diags);

  llvm::InitializeAllTargets();

  std::unique_ptr<Compilation> C = TheDriver.buildCompilation(argv);

  // In the event of an unrecoverable error, BuildCompilation will exit early,
  // so we can start with a 0 result code.
  int ResultCode = 0;
  if (C) {
    ResultCode = C->performJobs();
  }

  return ResultCode;
}
<commit_msg>[driver] Updated main() to return 1 if there were any errors building the Compilation.<commit_after>//===-- driver.cpp - Swift Compiler Driver --------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This is the entry point to the swift compiler driver.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticEngine.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Driver/Compilation.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/Job.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <memory>

using namespace swift;
using namespace swift::driver;

std::string getExecutablePath(const char *FirstArg) {
  void *P = (void *)(intptr_t)getExecutablePath;
  return llvm::sys::fs::getMainExecutable(FirstArg, P);
}

extern int frontend_main(ArrayRef<const char *> Args, const char *Argv0,
                         void *MainAddr);
extern int transform_ir_main(ArrayRef<const char *> Args, const char *Argv0,
                             void *MainAddr);

int main(int argc_, const char **argv_) {
  // Print a stack trace if we signal out.
  llvm::sys::PrintStackTraceOnErrorSignal();
  llvm::PrettyStackTraceProgram X(argc_, argv_);

  // Set up an object which will call llvm::llvm_shutdown() on exit.
  llvm::llvm_shutdown_obj Y;

  llvm::SmallVector<const char *, 256> argv;
  llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
  llvm::error_code EC = llvm::sys::Process::GetArgumentVector(argv,
                      llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
  if (EC) {
    llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
    return 1;
  }

  // Handle integrated tools.
  if (argv.size() > 1){
    StringRef FirstArg(argv[1]);
    if (FirstArg == "-frontend") {
      return frontend_main(llvm::makeArrayRef(argv.data()+2,
                                              argv.data()+argv.size()),
                           argv[0], (void *)(intptr_t)getExecutablePath);
    } else if (FirstArg == "-transform-ir") {
      return transform_ir_main(llvm::makeArrayRef(argv.data()+2,
                                                  argv.data()+argv.size()),
                               argv[0], (void *)(intptr_t)getExecutablePath);
    }
  }

  std::string Path = getExecutablePath(argv[0]);

  PrintingDiagnosticConsumer PDC;

  SourceManager SM;
  DiagnosticEngine Diags(SM);
  Diags.addConsumer(PDC);

  Driver TheDriver(Path, Diags);

  llvm::InitializeAllTargets();

  std::unique_ptr<Compilation> C = TheDriver.buildCompilation(argv);

  if (Diags.hadAnyError())
    return 1;

  if (C) {
    return C->performJobs();
  }

  return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix 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.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "file/config.h"
#include "gui/opengl/gl.h"
#include "gui/mrview/mode/base.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Mode
      {

        Base::Base (int flags) :
          projection (window().glarea, window().font),
          features (flags),
          update_overlays (false),
          visible (true) { }

        Base::~Base ()
        {
          glarea()->setCursor (Cursor::crosshair);
        }

        const Projection* Base::get_current_projection () const { return &projection; }

        void Base::paintGL ()
        {
          ASSERT_GL_MRVIEW_CONTEXT_IS_CURRENT;
          GL_CHECK_ERROR;

          projection.set_viewport (window(), 0, 0, width(), height());

          GL_CHECK_ERROR;
          gl::Clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
          if (!image()) {
            projection.setup_render_text();
            projection.render_text (10, 10, "No image loaded");
            projection.done_render_text();
            goto done_painting;
          }

          GL_CHECK_ERROR;
          if (!std::isfinite (focus().squaredNorm()) || !std::isfinite (target().squaredNorm()))
            reset_view();

          {
            GL_CHECK_ERROR;
            // call mode's draw method:
            paint (projection);

            gl::Disable (gl::MULTISAMPLE);
            GL_CHECK_ERROR;

            projection.setup_render_text();
            if (window().show_voxel_info()) {
              Eigen::Vector3f voxel (image()->transform().scanner2voxel.cast<float>() * focus());
              ssize_t vox [] = { ssize_t(std::round (voxel[0])), ssize_t(std::round (voxel[1])), ssize_t(std::round (voxel[2])) };

              std::string vox_str = printf ("voxel: [ %d %d %d ", vox[0], vox[1], vox[2]);
              for (size_t n = 3; n < image()->header().ndim(); ++n)
                vox_str += str(image()->image.index(n)) + " ";
              vox_str += "]";

              projection.render_text (printf ("position: [ %.4g %.4g %.4g ] mm", focus() [0], focus() [1], focus() [2]), LeftEdge | BottomEdge);
              projection.render_text (vox_str, LeftEdge | BottomEdge, 1);
              std::string value_str = "value: ";
              cfloat value = image()->interpolate() ?
                image()->trilinear_value (window().focus()) :
                image()->nearest_neighbour_value (window().focus());
              if (std::isfinite (std::abs (value)))
                value_str += str(value);
              else
                value_str += "?";

              projection.render_text (value_str, LeftEdge | BottomEdge, 2);

              // Draw additional labels from tools
              QList<QAction*> tools = window().tools()->actions();
              for (size_t i = 0, line_num = 3, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  line_num += dock->tool->draw_tool_labels (LeftEdge | BottomEdge, line_num, projection);
              }
            }
            GL_CHECK_ERROR;

            if (window().show_comments()) {
              for (size_t line = 0; line != image()->comments().size(); ++line)
                projection.render_text (image()->comments()[line], LeftEdge | TopEdge, line);
            }

            projection.done_render_text();

            GL_CHECK_ERROR;
            if (window().show_colourbar()) {

              auto &colourbar_renderer = window().colourbar_renderer;

              colourbar_renderer.begin_render_colourbars (&projection, window().colourbar_position, 1);
              colourbar_renderer.render (*image(), image()->scale_inverted());
              colourbar_renderer.end_render_colourbars ();

              QList<QAction*> tools = window().tools()->actions();
              size_t num_tool_colourbars = 0;
              for (size_t i = 0, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  num_tool_colourbars += dock->tool->visible_number_colourbars ();
              }

              colourbar_renderer.begin_render_colourbars (&projection, window().tools_colourbar_position, num_tool_colourbars);

              for (size_t i = 0, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  dock->tool->draw_colourbars ();
              }

              colourbar_renderer.end_render_colourbars ();

            }
            GL_CHECK_ERROR;

          }

done_painting:
          update_overlays = false;
          ASSERT_GL_MRVIEW_CONTEXT_IS_CURRENT;
        }

        void Base::paint (Projection&) { }
        void Base::mouse_press_event () { }
        void Base::mouse_release_event () { }

        void Base::slice_move_event (float x)
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          const auto &header = image()->header();
          float increment = snap_to_image() ?
            x * header.spacing (plane()) :
            x * std::pow (header.spacing(0) * header.spacing(1) * header.spacing(2), 1/3.f);
          move_in_out (increment, *proj);
          move_target_to_focus_plane (*proj);
          updateGL();
        }

        void Base::set_focus_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          set_focus (proj->screen_to_model (window().mouse_position(), focus()));
          updateGL();
        }

        void Base::contrast_event ()
        {
          image()->adjust_windowing (window().mouse_displacement());
          window().on_scaling_changed();
          updateGL();
        }

        void Base::pan_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          set_target (target() - proj->screen_to_model_direction (window().mouse_displacement(), target()));
          updateGL();
        }

        void Base::panthrough_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          move_in_out_FOV (window().mouse_displacement().y(), *proj);
          move_target_to_focus_plane (*proj);
          updateGL();
        }

        void Base::setup_projection (const int axis, Projection& with_projection) const
        {
          const GL::mat4 M = snap_to_image() ? GL::mat4 (image()->transform().image2scanner.matrix()) : GL::mat4 (orientation());
          setup_projection (adjust_projection_matrix (GL::transpose (M), axis), with_projection);
        }

        void Base::setup_projection (const Math::Versorf& V, Projection& with_projection) const
        {
          setup_projection (adjust_projection_matrix (GL::transpose (GL::mat4 (V))), with_projection);
        }

        void Base::setup_projection (const GL::mat4& M, Projection& with_projection) const
        {
          // info for projection:
          const int w = with_projection.width(), h = with_projection.height();
          const float fov = FOV() / (float)(w+h);
          const float depth = std::sqrt ( Math::pow2 (image()->header().spacing(0) * image()->header().size(0))
                                        + Math::pow2 (image()->header().spacing(1) * image()->header().size(1))
                                        + Math::pow2 (image()->header().spacing(2) * image()->header().size(2)));
          // set up projection & modelview matrices:
          const GL::mat4 P = GL::ortho (-w*fov, w*fov, -h*fov, h*fov, -depth, depth);
          const GL::mat4 MV = M * GL::translate (-target());
          with_projection.set (MV, P);
        }

        Math::Versorf Base::get_tilt_rotation () const
        {
          const Projection* proj = get_current_projection();
          if (!proj)
            return Math::Versorf();

          QPoint dpos = window().mouse_displacement();
          if (dpos.x() == 0 && dpos.y() == 0)
            return Math::Versorf();

          const Eigen::Vector3f x = proj->screen_to_model_direction (dpos, target());
          const Eigen::Vector3f z = proj->screen_normal();
          const Eigen::Vector3f v (x.cross (z).normalized());
          float angle = -ROTATION_INC * std::sqrt (float (Math::pow2 (dpos.x()) + Math::pow2 (dpos.y())));
          if (angle > Math::pi_2)
            angle = Math::pi_2;
          return Math::Versorf (Eigen::AngleAxisf (angle, v));
        }

        Math::Versorf Base::get_rotate_rotation () const
        {
          const Projection* proj = get_current_projection();
          if (!proj)
            return Math::Versorf();

          QPoint dpos = window().mouse_displacement();
          if (dpos.x() == 0 && dpos.y() == 0)
            return Math::Versorf();

          Eigen::Vector3f x1 (window().mouse_position().x() - proj->x_position() - proj->width()/2,
                              window().mouse_position().y() - proj->y_position() - proj->height()/2,
                              0.0);

          if (x1.norm() < 16.0f)
            return Math::Versorf();

          Eigen::Vector3f x0 (dpos.x() - x1[0], dpos.y() - x1[1], 0.0);

          x1.normalize();
          x0.normalize();

          const Eigen::Vector3f n = x1.cross (x0);
          const float angle = n[2];
          Eigen::Vector3f v = (proj->screen_normal()).normalized();
          return Math::Versorf (Eigen::AngleAxisf (angle, v));
        }

        void Base::tilt_event ()
        {
          if (snap_to_image())
            window().set_snap_to_image (false);

          const Math::Versorf rot = get_tilt_rotation();
          if (!rot)
            return;
          Math::Versorf orient = rot * orientation();
          set_orientation (orient);
          updateGL();
        }

        void Base::rotate_event ()
        {
          if (snap_to_image())
            window().set_snap_to_image (false);

          const Math::Versorf rot = get_rotate_rotation();
          if (!rot)
            return;
          Math::Versorf orient = rot * orientation();
          set_orientation (orient);
          updateGL();
        }

        void Base::reset_event ()
        {
          reset_view();
          updateGL();
        }

        void Base::reset_view ()
        {
          if (!image()) return;
          const Projection* proj = get_current_projection();
          if (!proj) return;

          float dim[] = {
            float(image()->header().size (0) * image()->header().spacing (0)),
            float(image()->header().size (1) * image()->header().spacing (1)),
            float(image()->header().size (2) * image()->header().spacing (2))
          };
          if (dim[0] < dim[1] && dim[0] < dim[2])
            set_plane (0);
          else if (dim[1] < dim[0] && dim[1] < dim[2])
            set_plane (1);
          else
            set_plane (2);

          Eigen::Vector3f p (
              std::floor ((image()->header().size(0)-1)/2.0f),
              std::floor ((image()->header().size(1)-1)/2.0f),
              std::floor ((image()->header().size(2)-1)/2.0f)
              );

          set_focus (image()->transform().voxel2scanner.cast<float>() * p);
          set_target (focus());
          reset_orientation();

          int x, y;
          image()->get_axes (plane(), x, y);
          set_FOV (std::max (dim[x], dim[y]));

          updateGL();
        }

        GL::mat4 Base::adjust_projection_matrix (const GL::mat4& Q, int proj) const
        {
          GL::mat4 M;
          M(3,0) = M(3,1) = M(3,2) = M(0,3) = M(1,3) = M(2,3) = 0.0f;
          M(3,3) = 1.0f;
          if (proj == 0) { // sagittal
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(1,n);  // x: -y
              M(1,n) =  Q(2,n);  // y: z
              M(2,n) = -Q(0,n);  // z: -x
            }
          }
          else if (proj == 1) { // coronal
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(0,n);  // x: -x
              M(1,n) =  Q(2,n);  // y: z
              M(2,n) =  Q(1,n);  // z: y
            }
          }
          else { // axial
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(0,n);  // x: -x
              M(1,n) =  Q(1,n);  // y: y
              M(2,n) = -Q(2,n);  // z: -z
            }
          }
          return M;
        }

      }
    }
  }
}

#undef MODE

<commit_msg>mrview: pan_event: removed updateGL() which causes pan gestures to remain in state Qt::GestureUpdated, never reaching Qt::GestureFinished on macOS #761. no negative side effects - I think<commit_after>/* Copyright (c) 2008-2017 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * MRtrix 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.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "file/config.h"
#include "gui/opengl/gl.h"
#include "gui/mrview/mode/base.h"

namespace MR
{
  namespace GUI
  {
    namespace MRView
    {
      namespace Mode
      {

        Base::Base (int flags) :
          projection (window().glarea, window().font),
          features (flags),
          update_overlays (false),
          visible (true) { }

        Base::~Base ()
        {
          glarea()->setCursor (Cursor::crosshair);
        }

        const Projection* Base::get_current_projection () const { return &projection; }

        void Base::paintGL ()
        {
          ASSERT_GL_MRVIEW_CONTEXT_IS_CURRENT;
          GL_CHECK_ERROR;

          projection.set_viewport (window(), 0, 0, width(), height());

          GL_CHECK_ERROR;
          gl::Clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
          if (!image()) {
            projection.setup_render_text();
            projection.render_text (10, 10, "No image loaded");
            projection.done_render_text();
            goto done_painting;
          }

          GL_CHECK_ERROR;
          if (!std::isfinite (focus().squaredNorm()) || !std::isfinite (target().squaredNorm()))
            reset_view();

          {
            GL_CHECK_ERROR;
            // call mode's draw method:
            paint (projection);

            gl::Disable (gl::MULTISAMPLE);
            GL_CHECK_ERROR;

            projection.setup_render_text();
            if (window().show_voxel_info()) {
              Eigen::Vector3f voxel (image()->transform().scanner2voxel.cast<float>() * focus());
              ssize_t vox [] = { ssize_t(std::round (voxel[0])), ssize_t(std::round (voxel[1])), ssize_t(std::round (voxel[2])) };

              std::string vox_str = printf ("voxel: [ %d %d %d ", vox[0], vox[1], vox[2]);
              for (size_t n = 3; n < image()->header().ndim(); ++n)
                vox_str += str(image()->image.index(n)) + " ";
              vox_str += "]";

              projection.render_text (printf ("position: [ %.4g %.4g %.4g ] mm", focus() [0], focus() [1], focus() [2]), LeftEdge | BottomEdge);
              projection.render_text (vox_str, LeftEdge | BottomEdge, 1);
              std::string value_str = "value: ";
              cfloat value = image()->interpolate() ?
                image()->trilinear_value (window().focus()) :
                image()->nearest_neighbour_value (window().focus());
              if (std::isfinite (std::abs (value)))
                value_str += str(value);
              else
                value_str += "?";

              projection.render_text (value_str, LeftEdge | BottomEdge, 2);

              // Draw additional labels from tools
              QList<QAction*> tools = window().tools()->actions();
              for (size_t i = 0, line_num = 3, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  line_num += dock->tool->draw_tool_labels (LeftEdge | BottomEdge, line_num, projection);
              }
            }
            GL_CHECK_ERROR;

            if (window().show_comments()) {
              for (size_t line = 0; line != image()->comments().size(); ++line)
                projection.render_text (image()->comments()[line], LeftEdge | TopEdge, line);
            }

            projection.done_render_text();

            GL_CHECK_ERROR;
            if (window().show_colourbar()) {

              auto &colourbar_renderer = window().colourbar_renderer;

              colourbar_renderer.begin_render_colourbars (&projection, window().colourbar_position, 1);
              colourbar_renderer.render (*image(), image()->scale_inverted());
              colourbar_renderer.end_render_colourbars ();

              QList<QAction*> tools = window().tools()->actions();
              size_t num_tool_colourbars = 0;
              for (size_t i = 0, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  num_tool_colourbars += dock->tool->visible_number_colourbars ();
              }

              colourbar_renderer.begin_render_colourbars (&projection, window().tools_colourbar_position, num_tool_colourbars);

              for (size_t i = 0, N = tools.size(); i < N; ++i) {
                Tool::Dock* dock = dynamic_cast<Tool::__Action__*>(tools[i])->dock;
                if (dock)
                  dock->tool->draw_colourbars ();
              }

              colourbar_renderer.end_render_colourbars ();

            }
            GL_CHECK_ERROR;

          }

done_painting:
          update_overlays = false;
          ASSERT_GL_MRVIEW_CONTEXT_IS_CURRENT;
        }

        void Base::paint (Projection&) { }
        void Base::mouse_press_event () { }
        void Base::mouse_release_event () { }

        void Base::slice_move_event (float x)
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          const auto &header = image()->header();
          float increment = snap_to_image() ?
            x * header.spacing (plane()) :
            x * std::pow (header.spacing(0) * header.spacing(1) * header.spacing(2), 1/3.f);
          move_in_out (increment, *proj);
          move_target_to_focus_plane (*proj);
          updateGL();
        }

        void Base::set_focus_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          set_focus (proj->screen_to_model (window().mouse_position(), focus()));
          updateGL();
        }

        void Base::contrast_event ()
        {
          image()->adjust_windowing (window().mouse_displacement());
          window().on_scaling_changed();
          updateGL();
        }

        void Base::pan_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          set_target (target() - proj->screen_to_model_direction (window().mouse_displacement(), target()));
          // updateGL(); # updateGL() causes pan gestures to remain in state Qt::GestureUpdated, never reaching Qt::GestureFinished on macOS
        }

        void Base::panthrough_event ()
        {
          const Projection* proj = get_current_projection();
          if (!proj) return;
          move_in_out_FOV (window().mouse_displacement().y(), *proj);
          move_target_to_focus_plane (*proj);
          updateGL();
        }

        void Base::setup_projection (const int axis, Projection& with_projection) const
        {
          const GL::mat4 M = snap_to_image() ? GL::mat4 (image()->transform().image2scanner.matrix()) : GL::mat4 (orientation());
          setup_projection (adjust_projection_matrix (GL::transpose (M), axis), with_projection);
        }

        void Base::setup_projection (const Math::Versorf& V, Projection& with_projection) const
        {
          setup_projection (adjust_projection_matrix (GL::transpose (GL::mat4 (V))), with_projection);
        }

        void Base::setup_projection (const GL::mat4& M, Projection& with_projection) const
        {
          // info for projection:
          const int w = with_projection.width(), h = with_projection.height();
          const float fov = FOV() / (float)(w+h);
          const float depth = std::sqrt ( Math::pow2 (image()->header().spacing(0) * image()->header().size(0))
                                        + Math::pow2 (image()->header().spacing(1) * image()->header().size(1))
                                        + Math::pow2 (image()->header().spacing(2) * image()->header().size(2)));
          // set up projection & modelview matrices:
          const GL::mat4 P = GL::ortho (-w*fov, w*fov, -h*fov, h*fov, -depth, depth);
          const GL::mat4 MV = M * GL::translate (-target());
          with_projection.set (MV, P);
        }

        Math::Versorf Base::get_tilt_rotation () const
        {
          const Projection* proj = get_current_projection();
          if (!proj)
            return Math::Versorf();

          QPoint dpos = window().mouse_displacement();
          if (dpos.x() == 0 && dpos.y() == 0)
            return Math::Versorf();

          const Eigen::Vector3f x = proj->screen_to_model_direction (dpos, target());
          const Eigen::Vector3f z = proj->screen_normal();
          const Eigen::Vector3f v (x.cross (z).normalized());
          float angle = -ROTATION_INC * std::sqrt (float (Math::pow2 (dpos.x()) + Math::pow2 (dpos.y())));
          if (angle > Math::pi_2)
            angle = Math::pi_2;
          return Math::Versorf (Eigen::AngleAxisf (angle, v));
        }

        Math::Versorf Base::get_rotate_rotation () const
        {
          const Projection* proj = get_current_projection();
          if (!proj)
            return Math::Versorf();

          QPoint dpos = window().mouse_displacement();
          if (dpos.x() == 0 && dpos.y() == 0)
            return Math::Versorf();

          Eigen::Vector3f x1 (window().mouse_position().x() - proj->x_position() - proj->width()/2,
                              window().mouse_position().y() - proj->y_position() - proj->height()/2,
                              0.0);

          if (x1.norm() < 16.0f)
            return Math::Versorf();

          Eigen::Vector3f x0 (dpos.x() - x1[0], dpos.y() - x1[1], 0.0);

          x1.normalize();
          x0.normalize();

          const Eigen::Vector3f n = x1.cross (x0);
          const float angle = n[2];
          Eigen::Vector3f v = (proj->screen_normal()).normalized();
          return Math::Versorf (Eigen::AngleAxisf (angle, v));
        }

        void Base::tilt_event ()
        {
          if (snap_to_image())
            window().set_snap_to_image (false);

          const Math::Versorf rot = get_tilt_rotation();
          if (!rot)
            return;
          Math::Versorf orient = rot * orientation();
          set_orientation (orient);
          updateGL();
        }

        void Base::rotate_event ()
        {
          if (snap_to_image())
            window().set_snap_to_image (false);

          const Math::Versorf rot = get_rotate_rotation();
          if (!rot)
            return;
          Math::Versorf orient = rot * orientation();
          set_orientation (orient);
          updateGL();
        }

        void Base::reset_event ()
        {
          reset_view();
          updateGL();
        }

        void Base::reset_view ()
        {
          if (!image()) return;
          const Projection* proj = get_current_projection();
          if (!proj) return;

          float dim[] = {
            float(image()->header().size (0) * image()->header().spacing (0)),
            float(image()->header().size (1) * image()->header().spacing (1)),
            float(image()->header().size (2) * image()->header().spacing (2))
          };
          if (dim[0] < dim[1] && dim[0] < dim[2])
            set_plane (0);
          else if (dim[1] < dim[0] && dim[1] < dim[2])
            set_plane (1);
          else
            set_plane (2);

          Eigen::Vector3f p (
              std::floor ((image()->header().size(0)-1)/2.0f),
              std::floor ((image()->header().size(1)-1)/2.0f),
              std::floor ((image()->header().size(2)-1)/2.0f)
              );

          set_focus (image()->transform().voxel2scanner.cast<float>() * p);
          set_target (focus());
          reset_orientation();

          int x, y;
          image()->get_axes (plane(), x, y);
          set_FOV (std::max (dim[x], dim[y]));

          updateGL();
        }

        GL::mat4 Base::adjust_projection_matrix (const GL::mat4& Q, int proj) const
        {
          GL::mat4 M;
          M(3,0) = M(3,1) = M(3,2) = M(0,3) = M(1,3) = M(2,3) = 0.0f;
          M(3,3) = 1.0f;
          if (proj == 0) { // sagittal
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(1,n);  // x: -y
              M(1,n) =  Q(2,n);  // y: z
              M(2,n) = -Q(0,n);  // z: -x
            }
          }
          else if (proj == 1) { // coronal
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(0,n);  // x: -x
              M(1,n) =  Q(2,n);  // y: z
              M(2,n) =  Q(1,n);  // z: y
            }
          }
          else { // axial
            for (size_t n = 0; n < 3; n++) {
              M(0,n) = -Q(0,n);  // x: -x
              M(1,n) =  Q(1,n);  // y: y
              M(2,n) = -Q(2,n);  // z: -z
            }
          }
          return M;
        }

      }
    }
  }
}

#undef MODE

<|endoftext|>


<commit_before><commit_msg>gui: check across all layers to determine rotation<commit_after><|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013-2014, Luke Goddard. 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 Luke Goddard nor the names of any
//       other contributors to this software 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 <iostream>

#include "boost/test/test_tools.hpp"
#include "boost/test/results_reporter.hpp"
#include "boost/test/unit_test_suite.hpp"
#include "boost/test/output_test_stream.hpp"
#include "boost/test/unit_test_log.hpp"
#include "boost/test/framework.hpp"
#include "boost/test/detail/unit_test_parameters.hpp"

#include "GanderTest/LevenbergMarquardtTest.h"
#include "GanderTest/HomographyTest.h"
#include "GanderTest/AngleConversionTest.h"
#include "GanderTest/DecomposeRQ3x3Test.h"
#include "GanderTest/CommonTest.h"
#include "GanderTest/EnumHelperTest.h"
#include "GanderTest/BitTwiddlerTest.h"

using namespace boost::unit_test;
using boost::test_tools::output_test_stream;

using namespace Gander;
using namespace Gander::Test;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
	test_suite* test = BOOST_TEST_SUITE( "Gander unit test" );

	try
	{
		addLevenbergMarquardtTest(test);
		addHomographyTest(test);
		addDecomposeRQ3x3Test(test);
		addAngleConversionTest(test);
		addCommonTest(test);
		addEnumHelperTest(test);
		addBitTwiddlerTest(test);
	}
	catch (std::exception &ex)
	{
		std::cerr << "Failed to create test suite: " << ex.what() << std::endl;
		throw;
	}

	return test;
}
<commit_msg>Made calls to the Tuple and Interface test cases.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013-2014, Luke Goddard. 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 Luke Goddard nor the names of any
//       other contributors to this software 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 <iostream>

#include "boost/test/test_tools.hpp"
#include "boost/test/results_reporter.hpp"
#include "boost/test/unit_test_suite.hpp"
#include "boost/test/output_test_stream.hpp"
#include "boost/test/unit_test_log.hpp"
#include "boost/test/framework.hpp"
#include "boost/test/detail/unit_test_parameters.hpp"

#include "GanderTest/LevenbergMarquardtTest.h"
#include "GanderTest/HomographyTest.h"
#include "GanderTest/AngleConversionTest.h"
#include "GanderTest/DecomposeRQ3x3Test.h"
#include "GanderTest/CommonTest.h"
#include "GanderTest/EnumHelperTest.h"
#include "GanderTest/BitTwiddlerTest.h"
#include "GanderTest/TupleTest.h"
#include "GanderTest/InterfacesTest.h"

using namespace boost::unit_test;
using boost::test_tools::output_test_stream;

using namespace Gander;
using namespace Gander::Test;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
	test_suite* test = BOOST_TEST_SUITE( "Gander unit test" );

	try
	{
		addLevenbergMarquardtTest(test);
		addHomographyTest(test);
		addDecomposeRQ3x3Test(test);
		addAngleConversionTest(test);
		addCommonTest(test);
		addEnumHelperTest(test);
		addBitTwiddlerTest(test);
		addTupleTest(test);
		addInterfacesTest(test);
	}
	catch (std::exception &ex)
	{
		std::cerr << "Failed to create test suite: " << ex.what() << std::endl;
		throw;
	}

	return test;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. 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 Image Engine Design nor the names of any
//       other contributors to this software 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 "IECore/CINImageWriter.h"
#include "IECore/MessageHandler.h"
#include "IECore/VectorTypedData.h"
#include "IECore/ByteOrder.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/FileNameParameter.h"
#include "IECore/DataConvert.h"
#include "IECore/ScaledDataConversion.h"
#include "IECore/CompoundDataConversion.h"
#include "IECore/LinearToCineonDataConversion.h"
#include "IECore/DespatchTypedData.h"

#include "IECore/private/cineon.h"

#include "boost/format.hpp"

#include <fstream>
#include <time.h>

using namespace IECore;
using namespace std;
using namespace boost;
using namespace Imath;

const Writer::WriterDescription<CINImageWriter> CINImageWriter::m_writerDescription("cin");

CINImageWriter::CINImageWriter() :
		ImageWriter("CINImageWriter", "Serializes images to the Kodak Cineon 10-bit log image format")
{
}

CINImageWriter::CINImageWriter( ObjectPtr image, const string &fileName ) :
		ImageWriter("CINImageWriter", "Serializes images to the Kodak Cineon 10-bit log image format")
{
	m_objectParameter->setValue( image );
	m_fileNameParameter->setTypedValue( fileName );
}

CINImageWriter::~CINImageWriter()
{
}

struct CINImageWriter::ChannelConverter
{
	typedef void ReturnType;

	std::string m_channelName;
	Box2i m_displayWindow;
	Box2i m_dataWindow;
	unsigned int m_bitShift;
	std::vector<unsigned int> &m_imageBuffer;

	ChannelConverter( const std::string &channelName, const Box2i &displayWindow, const Box2i &dataWindow, unsigned int bitShift, std::vector<unsigned int> &imageBuffer  )
	: m_channelName( channelName ), m_displayWindow( displayWindow ), m_dataWindow( dataWindow ), m_bitShift( bitShift ), m_imageBuffer( imageBuffer )
	{
	}

	template<typename T>
	ReturnType operator()( typename T::Ptr dataContainer )
	{
		assert( dataContainer );

		const typename T::ValueType &data = dataContainer->readable();

		CompoundDataConversion<
			ScaledDataConversion<typename T::ValueType::value_type, float>,
			LinearToCineonDataConversion<float, unsigned int>
		> converter;

		int displayWidth = m_displayWindow.size().x + 1;
		int dataWidth = m_dataWindow.size().x + 1;

		int dataY = 0;

		for ( int y = m_dataWindow.min.y; y <= m_dataWindow.max.y; y++, dataY++ )
		{
			int dataOffset = dataY * dataWidth ;
			assert( dataOffset >= 0 );

			for ( int x = m_dataWindow.min.x; x <= m_dataWindow.max.x; x++, dataOffset++ )
			{
				int pixelIdx = ( y - m_displayWindow.min.y ) * displayWidth + ( x - m_displayWindow.min.x );

				assert( pixelIdx >= 0 );
				assert( pixelIdx < (int)m_imageBuffer.size() );
				assert( dataOffset < (int)data.size() );

				/// Perform the conversion, and set the appropriate bits in the "cell"
				m_imageBuffer[ pixelIdx ] |= converter( data[dataOffset] ) << m_bitShift;
			}
		}
	};

	struct ErrorHandler
	{
		template<typename T, typename F>
		void operator()( typename T::ConstPtr data, const F& functor )
		{
			assert( data );

			throw InvalidArgumentException( ( boost::format( "CINImageWriter: Invalid data type \"%s\" for channel \"%s\"." ) % Object::typeNameFromTypeId( data->typeId() ) % functor.m_channelName ).str() );
		}
	};
};

void CINImageWriter::writeImage( const vector<string> &names, ConstImagePrimitivePtr image, const Box2i &dataWindow ) const
{
	// write the cineon in the standard 10bit log format
	std::ofstream out;
	out.open(fileName().c_str());
	if (!out.is_open())
	{
		throw IOException( "CINImageWriter: Could not open " + fileName() );
	}

	/// We'd like RGB to be at the front, in that order, because it seems that not all readers support the channel identifiers!
	vector<string> desiredChannelOrder;
	desiredChannelOrder.push_back( "R" );
	desiredChannelOrder.push_back( "G" );
	desiredChannelOrder.push_back( "B" );

	vector<string> namesCopy = names;
	vector<string> filteredNames;

	for ( vector<string>::const_iterator it = desiredChannelOrder.begin(); it != desiredChannelOrder.end(); ++it )
	{
		vector<string>::iterator res = find( namesCopy.begin(), namesCopy.end(), *it );
		if ( res != namesCopy.end() )
		{
			namesCopy.erase( res );
			filteredNames.push_back( *it );
		}
	}

	for ( vector<string>::const_iterator it = namesCopy.begin(); it != namesCopy.end(); ++it )
	{
		filteredNames.push_back( *it );
	}

	assert( names.size() == filteredNames.size() );

	Box2i displayWindow = image->getDisplayWindow();

	int displayWidth  = 1 + displayWindow.size().x;
	int displayHeight = 1 + displayWindow.size().y;

	// build the header
	FileInformation fi;
	fi.magic = asBigEndian<>( 0x802a5fd7 );

	fi.section_header_length = 0;
	fi.industry_header_length = 0;
	fi.variable_header_length = 0;

	strcpy(fi.version, "V4.5");

	strncpy( (char *) fi.file_name, fileName().c_str(), sizeof( fi.file_name ) );

	// compute the current date and time
	time_t t;
	time(&t);
	struct tm gmt;
	localtime_r(&t, &gmt);

	snprintf(fi.creation_date, sizeof( fi.creation_date ), "%04d-%02d-%02d", 1900 + gmt.tm_year, gmt.tm_mon, gmt.tm_mday);
	snprintf(fi.creation_time, sizeof( fi.creation_time ), "%02d:%02d:%02d", gmt.tm_hour, gmt.tm_min, gmt.tm_sec);

	ImageInformation ii;
	ii.orientation = 0;
	ii.channel_count = 0;

	for (int c = 0; c < 8; ++c)
	{
		ImageInformationChannelInformation &ci = ii.channel_information[c];
		ci.byte_0 = 0;
		ci.byte_1 = 0;
		ci.bpp = 10;

		ci.pixels_per_line = 0;
		ci.lines_per_image = 0;
	}

	// write the data
	std::vector<unsigned int> imageBuffer( displayWidth*displayHeight, 0 );

	vector<string>::const_iterator i = filteredNames.begin();
	int offset = 0;
	while (i != filteredNames.end())
	{
		if (!(*i == "R" || *i == "G" || *i == "B" || *i == "Y"))
		{
			msg( Msg::Warning, "CINImageWriter::write", format( "Channel \"%s\" was not encoded." ) % *i );
			++i;
			continue;
		}

		ImageInformationChannelInformation &ci = ii.channel_information[offset];
		ci.byte_0 = 0;

		if ( *i == "R" )
		{
			ci.byte_1 = 1;
		}
		else if ( *i == "G" )
		{
			ci.byte_1 = 2;
		}
		else if ( *i == "B" )
		{
			ci.byte_1 = 3;
		}
		else if ( *i == "Y" )
		{
			ci.byte_1 = 0;
		}

		ci.bpp = 10;

		ci.pixels_per_line = asBigEndian<>( displayWidth );
		ci.lines_per_image = asBigEndian<>( displayHeight );

		/// \todo Document these constants
		ci.min_data_value = 0.0;
		ci.min_quantity = 0.0;
		ci.max_data_value = 1023.0;
		ci.max_quantity = 2.046;

		ci.min_data_value = asBigEndian<>( ci.min_data_value );
		ci.min_quantity   = asBigEndian<>( ci.min_quantity );
		ci.max_data_value = asBigEndian<>( ci.max_data_value );
		ci.min_quantity   = asBigEndian<>( ci.max_quantity );

		int bpp = 10;
		unsigned int shift = (32 - bpp) - (offset*bpp);

		assert( image->variables.find( *i ) != image->variables.end() );
		DataPtr dataContainer = image->variables.find( *i )->second.data;
		assert( dataContainer );

		ChannelConverter converter( *i, image->getDisplayWindow(), dataWindow, shift, imageBuffer );

		despatchTypedData<
			ChannelConverter,
			TypeTraits::IsNumericVectorTypedData,
			ChannelConverter::ErrorHandler
		>( dataContainer, converter );

		ii.channel_count ++;

		++offset;

		++i;
	}

	if ( ii.channel_count < 1 || ii.channel_count > 3 )
	{
		throw IOException( "CINImageWriter: Invalid number of channels" );
	}

	ImageDataFormatInformation idfi;
	idfi.interleave = 0;               // pixel interleave
	idfi.packing = 5;                  // 32 bit left-aligned with 2 waste bits
	idfi.data_signed = 0;              // unsigned data
	idfi.sense = 0;                    // positive image sense
	idfi.eol_padding = 0;              // no end-of-line padding
	idfi.eoc_padding = 0;              // no end-of-data padding

	/// \todo Complete filling in this structure
	ImageOriginationInformation ioi;
	ioi.x_offset = 0;                  // could be dataWindow min.x
	ioi.y_offset = 0;                  // could be dataWindow min.y
	ioi.gamma = 0x7f800000;
	ioi.gamma = asBigEndian<>(ioi.gamma);

	// compute data offsets
	fi.image_data_offset = 1024;
	fi.image_data_offset = asBigEndian<>(fi.image_data_offset);

	// file size is 1024 (header) + image data size
	// image data size is 32 bits times width*height
	fi.total_file_size = 1024 + sizeof( unsigned int ) * displayWidth * displayHeight;
	fi.total_file_size = asBigEndian<>(fi.total_file_size);

	out.write(reinterpret_cast<char *>(&fi),   sizeof(fi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&ii),   sizeof(ii));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&idfi), sizeof(idfi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&ioi),  sizeof(ioi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	// write the buffer
	for (int i = 0; i < displayWidth*displayHeight; ++i)
	{
		imageBuffer[i] = asBigEndian<>(imageBuffer[i]);
		out.write((const char *) (&imageBuffer[i]), sizeof(unsigned int));
		if ( out.fail() )
		{
			throw IOException( "CINImageWriter: Error writing to " + fileName() );
		}
	}
}
<commit_msg>Added assert and todo<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. 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 Image Engine Design nor the names of any
//       other contributors to this software 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 "IECore/CINImageWriter.h"
#include "IECore/MessageHandler.h"
#include "IECore/VectorTypedData.h"
#include "IECore/ByteOrder.h"
#include "IECore/ImagePrimitive.h"
#include "IECore/FileNameParameter.h"
#include "IECore/DataConvert.h"
#include "IECore/ScaledDataConversion.h"
#include "IECore/CompoundDataConversion.h"
#include "IECore/LinearToCineonDataConversion.h"
#include "IECore/DespatchTypedData.h"

#include "IECore/private/cineon.h"

#include "boost/format.hpp"

#include <fstream>
#include <time.h>

using namespace IECore;
using namespace std;
using namespace boost;
using namespace Imath;

const Writer::WriterDescription<CINImageWriter> CINImageWriter::m_writerDescription("cin");

CINImageWriter::CINImageWriter() :
		ImageWriter("CINImageWriter", "Serializes images to the Kodak Cineon 10-bit log image format")
{
}

CINImageWriter::CINImageWriter( ObjectPtr image, const string &fileName ) :
		ImageWriter("CINImageWriter", "Serializes images to the Kodak Cineon 10-bit log image format")
{
	m_objectParameter->setValue( image );
	m_fileNameParameter->setTypedValue( fileName );
}

CINImageWriter::~CINImageWriter()
{
}

struct CINImageWriter::ChannelConverter
{
	typedef void ReturnType;

	std::string m_channelName;
	Box2i m_displayWindow;
	Box2i m_dataWindow;
	unsigned int m_bitShift;
	std::vector<unsigned int> &m_imageBuffer;

	ChannelConverter( const std::string &channelName, const Box2i &displayWindow, const Box2i &dataWindow, unsigned int bitShift, std::vector<unsigned int> &imageBuffer  )
	: m_channelName( channelName ), m_displayWindow( displayWindow ), m_dataWindow( dataWindow ), m_bitShift( bitShift ), m_imageBuffer( imageBuffer )
	{
	}

	template<typename T>
	ReturnType operator()( typename T::Ptr dataContainer )
	{
		assert( dataContainer );

		const typename T::ValueType &data = dataContainer->readable();

		CompoundDataConversion<
			ScaledDataConversion<typename T::ValueType::value_type, float>,
			LinearToCineonDataConversion<float, unsigned int>
		> converter;

		int displayWidth = m_displayWindow.size().x + 1;
		int dataWidth = m_dataWindow.size().x + 1;

		int dataY = 0;

		for ( int y = m_dataWindow.min.y; y <= m_dataWindow.max.y; y++, dataY++ )
		{
			int dataOffset = dataY * dataWidth ;
			assert( dataOffset >= 0 );

			for ( int x = m_dataWindow.min.x; x <= m_dataWindow.max.x; x++, dataOffset++ )
			{
				int pixelIdx = ( y - m_displayWindow.min.y ) * displayWidth + ( x - m_displayWindow.min.x );

				assert( pixelIdx >= 0 );
				assert( pixelIdx < (int)m_imageBuffer.size() );
				assert( dataOffset < (int)data.size() );

				/// Perform the conversion, and set the appropriate bits in the "cell"
				m_imageBuffer[ pixelIdx ] |= converter( data[dataOffset] ) << m_bitShift;
			}
		}
	};

	struct ErrorHandler
	{
		template<typename T, typename F>
		void operator()( typename T::ConstPtr data, const F& functor )
		{
			assert( data );

			throw InvalidArgumentException( ( boost::format( "CINImageWriter: Invalid data type \"%s\" for channel \"%s\"." ) % Object::typeNameFromTypeId( data->typeId() ) % functor.m_channelName ).str() );
		}
	};
};

void CINImageWriter::writeImage( const vector<string> &names, ConstImagePrimitivePtr image, const Box2i &dataWindow ) const
{
	// write the cineon in the standard 10bit log format
	std::ofstream out;
	out.open(fileName().c_str());
	if (!out.is_open())
	{
		throw IOException( "CINImageWriter: Could not open " + fileName() );
	}

	/// We'd like RGB to be at the front, in that order, because it seems that not all readers support the channel identifiers!
	vector<string> desiredChannelOrder;
	desiredChannelOrder.push_back( "R" );
	desiredChannelOrder.push_back( "G" );
	desiredChannelOrder.push_back( "B" );

	vector<string> namesCopy = names;
	vector<string> filteredNames;

	for ( vector<string>::const_iterator it = desiredChannelOrder.begin(); it != desiredChannelOrder.end(); ++it )
	{
		vector<string>::iterator res = find( namesCopy.begin(), namesCopy.end(), *it );
		if ( res != namesCopy.end() )
		{
			namesCopy.erase( res );
			filteredNames.push_back( *it );
		}
	}

	for ( vector<string>::const_iterator it = namesCopy.begin(); it != namesCopy.end(); ++it )
	{
		filteredNames.push_back( *it );
	}

	assert( names.size() == filteredNames.size() );

	Box2i displayWindow = image->getDisplayWindow();

	int displayWidth  = 1 + displayWindow.size().x;
	int displayHeight = 1 + displayWindow.size().y;

	// build the header
	FileInformation fi;
	fi.magic = asBigEndian<>( 0x802a5fd7 );

	fi.section_header_length = 0;
	fi.industry_header_length = 0;
	fi.variable_header_length = 0;

	strcpy(fi.version, "V4.5");

	strncpy( (char *) fi.file_name, fileName().c_str(), sizeof( fi.file_name ) );

	// compute the current date and time
	time_t t;
	time(&t);
	struct tm gmt;
	localtime_r(&t, &gmt);

	snprintf(fi.creation_date, sizeof( fi.creation_date ), "%04d-%02d-%02d", 1900 + gmt.tm_year, gmt.tm_mon, gmt.tm_mday);
	snprintf(fi.creation_time, sizeof( fi.creation_time ), "%02d:%02d:%02d", gmt.tm_hour, gmt.tm_min, gmt.tm_sec);

	ImageInformation ii;
	ii.orientation = 0;
	ii.channel_count = 0;

	for (int c = 0; c < 8; ++c)
	{
		ImageInformationChannelInformation &ci = ii.channel_information[c];
		ci.byte_0 = 0;
		ci.byte_1 = 0;
		ci.bpp = 10;

		ci.pixels_per_line = 0;
		ci.lines_per_image = 0;
	}

	// write the data
	std::vector<unsigned int> imageBuffer( displayWidth*displayHeight, 0 );

	vector<string>::const_iterator i = filteredNames.begin();
	int offset = 0;
	while (i != filteredNames.end())
	{
		if (!(*i == "R" || *i == "G" || *i == "B" || *i == "Y"))
		{
			msg( Msg::Warning, "CINImageWriter::write", format( "Channel \"%s\" was not encoded." ) % *i );
			++i;
			continue;
		}

		ImageInformationChannelInformation &ci = ii.channel_information[offset];
		ci.byte_0 = 0;

		if ( *i == "R" )
		{
			ci.byte_1 = 1;
		}
		else if ( *i == "G" )
		{
			ci.byte_1 = 2;
		}
		else if ( *i == "B" )
		{
			ci.byte_1 = 3;
		}
		else if ( *i == "Y" )
		{
			ci.byte_1 = 0;
		}

		ci.bpp = 10;

		ci.pixels_per_line = asBigEndian<>( displayWidth );
		ci.lines_per_image = asBigEndian<>( displayHeight );

		/// \todo Document these constants
		ci.min_data_value = 0.0;
		ci.min_quantity = 0.0;
		ci.max_data_value = 1023.0;
		ci.max_quantity = 2.046;

		ci.min_data_value = asBigEndian<>( ci.min_data_value );
		ci.min_quantity   = asBigEndian<>( ci.min_quantity );
		ci.max_data_value = asBigEndian<>( ci.max_data_value );
		ci.min_quantity   = asBigEndian<>( ci.max_quantity );

		int bpp = 10;
		unsigned int shift = (32 - bpp) - (offset*bpp);

		assert( image->variables.find( *i ) != image->variables.end() );
		DataPtr dataContainer = image->variables.find( *i )->second.data;
		assert( dataContainer );

		ChannelConverter converter( *i, image->getDisplayWindow(), dataWindow, shift, imageBuffer );

		despatchTypedData<
			ChannelConverter,
			TypeTraits::IsNumericVectorTypedData,
			ChannelConverter::ErrorHandler
		>( dataContainer, converter );

		ii.channel_count ++;

		++offset;

		++i;
	}

	if ( ii.channel_count < 1 || ii.channel_count > 3 )
	{
		throw IOException( "CINImageWriter: Invalid number of channels" );
	}

	ImageDataFormatInformation idfi;
	idfi.interleave = 0;               // pixel interleave
	idfi.packing = 5;                  // 32 bit left-aligned with 2 waste bits
	idfi.data_signed = 0;              // unsigned data
	idfi.sense = 0;                    // positive image sense
	idfi.eol_padding = 0;              // no end-of-line padding
	idfi.eoc_padding = 0;              // no end-of-data padding

	/// \todo Complete filling in this structure
	ImageOriginationInformation ioi;
	ioi.x_offset = 0;                  // could be dataWindow min.x
	ioi.y_offset = 0;                  // could be dataWindow min.y
	ioi.gamma = 0x7f800000;
	ioi.gamma = asBigEndian<>(ioi.gamma);

	// compute data offsets
	fi.image_data_offset = 1024;
	fi.image_data_offset = asBigEndian<>(fi.image_data_offset);

	// file size is 1024 (header) + image data size
	// image data size is 32 bits times width*height
	fi.total_file_size = 1024 + sizeof( unsigned int ) * displayWidth * displayHeight;
	fi.total_file_size = asBigEndian<>(fi.total_file_size);

	out.write(reinterpret_cast<char *>(&fi),   sizeof(fi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&ii),   sizeof(ii));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&idfi), sizeof(idfi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	out.write(reinterpret_cast<char *>(&ioi),  sizeof(ioi));
	if ( out.fail() )
	{
		throw IOException( "CINImageWriter: Error writing to " + fileName() );
	}

	// write the buffer
	for (int i = 0; i < displayWidth*displayHeight; ++i)
	{
		assert( i < (int)imageBuffer.size() );
		imageBuffer[i] = asBigEndian<>(imageBuffer[i]);
		/// \todo The following line has been seen to generate a valgrind warning that the system functions
		/// called from within are attempting to access uninitialized data. Establish why.
		out.write((const char *) (&imageBuffer[i]), sizeof(unsigned int));
		if ( out.fail() )
		{
			throw IOException( "CINImageWriter: Error writing to " + fileName() );
		}
	}
}
<|endoftext|>


<commit_before>/**
 * @project identt
 * @file src/http/NotFoundService.hpp
 * @author  S Roychowdhury <sroycode AT gmail DOT com>
 * @version 1.0.0
 *
 * @section LICENSE
 *
 * Copyright (c) 2017 S Roychowdhury.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 *  NotFoundService.hpp :   NotFound Server Implementation
 *
 */
#ifndef _IDENTT_HTTP_NOTFOUNDSERVICE_HPP_
#define _IDENTT_HTTP_NOTFOUNDSERVICE_HPP_

#include <http/ServiceBase.hpp>

namespace identt {
namespace http {

template <class HttpServerT>
class NotFoundService : protected identt::http::ServiceBase<HttpServerT> {
public:

	/**
	* NotFoundService : constructor
	*
	* @param context
	*   identt::utils::SharedTable::pointer stptr
	*
	* @param server
	*   HttpServerT server
	*
	* @param scope
	*   unsigned int scope check
	*
	* @return
	*   none
	*/

	NotFoundService(identt::utils::SharedTable::pointer stptr,
		typename std::shared_ptr<HttpServerT> server,
		unsigned int scope)
		: identt::http::ServiceBase<HttpServerT>(IDENTT_SERVICE_SCOPE_HTTP | IDENTT_SERVICE_SCOPE_HTTPS)
	{
		if (!(this->myscope & scope)) return; // scope mismatch
		server->default_resource["GET"] =
		[this](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
			this->HttpErrorAction(response,request,404,"NOT FOUND");
		};
		server->default_resource["POST"] =
		[this](typename HttpServerT::RespPtr response, typename HttpServerT::ReqPtr request) {
			this->HttpErrorAction(response,request,404,"NOT FOUND");
		};
	}

private:
};

} // namespace http
} // namespace identt

#endif // _IDENTT_HTTP_NOTFOUNDSERVICE_HPP_
<commit_msg>changed the thirdparty building script<commit_after><|endoftext|>