<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/**************************************************************************
  UIOBuffer.cc

**************************************************************************/
#include "P_EventSystem.h"

//
// General Buffer Allocator
//
inkcoreapi Allocator ioBufAllocator[DEFAULT_BUFFER_SIZES];
inkcoreapi ClassAllocator<MIOBuffer> ioAllocator("ioAllocator", DEFAULT_BUFFER_NUMBER);
inkcoreapi ClassAllocator<IOBufferData> ioDataAllocator("ioDataAllocator", DEFAULT_BUFFER_NUMBER);
inkcoreapi ClassAllocator<IOBufferBlock> ioBlockAllocator("ioBlockAllocator", DEFAULT_BUFFER_NUMBER);
int64_t default_large_iobuffer_size = DEFAULT_LARGE_BUFFER_SIZE;
int64_t default_small_iobuffer_size = DEFAULT_SMALL_BUFFER_SIZE;
int64_t max_iobuffer_size = DEFAULT_BUFFER_SIZES - 1;

//
// Initialization
//
void
init_buffer_allocators()
{
  char *name;
  int advice = 0;

#ifdef MADV_DONTDUMP // This should only exist on Linux 3.4 and higher.
  advice = MADV_DONTDUMP;
#endif

  for (int i = 0; i < DEFAULT_BUFFER_SIZES; i++) {
    int64_t s = DEFAULT_BUFFER_BASE_SIZE * (((int64_t)1) << i);
    int64_t a = DEFAULT_BUFFER_ALIGNMENT;
    int n = i <= default_large_iobuffer_size ? DEFAULT_BUFFER_NUMBER : DEFAULT_HUGE_BUFFER_NUMBER;
    if (s < a)
      a = s;

    name = new char[64];
    snprintf(name, 64, "ioBufAllocator[%d]", i);
    ioBufAllocator[i].re_init(name, s, n, a, advice);
  }
}

int64_t
MIOBuffer::remove_append(IOBufferReader * r)
{
  int64_t l = 0;
  while (r->block) {
    Ptr<IOBufferBlock> b = r->block;
    r->block = r->block->next;
    b->_start += r->start_offset;
    if (b->start() >= b->end()) {
      r->start_offset = -r->start_offset;
      continue;
    }
    r->start_offset = 0;
    l += b->read_avail();
    append_block(b);
  }
  r->mbuf->_writer = NULL;
  return l;
}

int64_t
MIOBuffer::write(const void *abuf, int64_t alen)
{
  const char *buf = (const char*)abuf;
  int64_t len = alen;
  while (len) {
    if (!_writer)
      add_block();
    int64_t f = _writer->write_avail();
    f = f < len ? f : len;
    if (f > 0) {
      ::memcpy(_writer->end(), buf, f);
      _writer->fill(f);
      buf += f;
      len -= f;
    }
    if (len) {
      if (!_writer->next)
        add_block();
      else
        _writer = _writer->next;
    }
  }
  return alen;
}

#ifdef WRITE_AND_TRANSFER
  /*
   * Same functionality as write but for the one small difference.
   * The space available in the last block is taken from the original
   * and this space becomes available to the copy.
   *
   */
int64_t
MIOBuffer::write_and_transfer_left_over_space(IOBufferReader * r, int64_t alen, int64_t offset)
{
  int64_t rval = write(r, alen, offset);
  // reset the end markers of the original so that it cannot
  // make use of the space in the current block
  if (r->mbuf->_writer)
    r->mbuf->_writer->_buf_end = r->mbuf->_writer->_end;
  // reset the end marker of the clone so that it can make
  // use of the space in the current block
  if (_writer) {
    _writer->_buf_end = _writer->data->data() + _writer->block_size();
  }
  return rval;
}

#endif

int64_t
MIOBuffer::write(IOBufferReader * r, int64_t alen, int64_t offset)
{
  int64_t len = alen;
  IOBufferBlock *b = r->block;
  offset += r->start_offset;

  while (b && len > 0) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    IOBufferBlock *bb = b->clone();
    bb->_start += offset;
    bb->_buf_end = bb->_end = bb->_start + bytes;
    append_block(bb);
    offset = 0;
    len -= bytes;
    b = b->next;
  }
  return alen - len;
}

int64_t
MIOBuffer::puts(char *s, int64_t len)
{
  char *pc = end();
  char *pb = s;
  while (pc < buf_end()) {
    if (len-- <= 0)
      return -1;
    if (!*pb || *pb == '\n') {
      int64_t n = (int64_t) (pb - s);
      memcpy(end(), s, n + 1);  // Upto and including '\n'
      end()[n + 1] = 0;
      fill(n + 1);
      return n + 1;
    }
    pc++;
    pb++;
  }
  return 0;
}

int64_t
IOBufferReader::read(void *ab, int64_t len)
{
  char *b = (char*)ab;
  int64_t max_bytes = read_avail();
  int64_t bytes = len <= max_bytes ? len : max_bytes;
  int64_t n = bytes;

  while (n) {
    int64_t l = block_read_avail();
    if (n < l)
      l = n;
    ::memcpy(b, start(), l);
    consume(l);
    b += l;
    n -= l;
  }
  return bytes;
}

// TODO: I don't think this method is used anywhere, so perhaps get rid of it ?
int64_t
IOBufferReader::memchr(char c, int64_t len, int64_t offset)
{
  IOBufferBlock *b = block;
  offset += start_offset;
  int64_t o = offset;

  while (b && len) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    char *s = b->start() + offset;
    char *p = (char *) ::memchr(s, c, bytes);
    if (p)
      return (int64_t) (o - start_offset + p - s);
    o += bytes;
    len -= bytes;
    b = b->next;
    offset = 0;
  }

  return -1;
}

char *
IOBufferReader::memcpy(const void *ap, int64_t len, int64_t offset)
{
  char *p = (char*)ap;
  IOBufferBlock *b = block;
  offset += start_offset;

  while (b && len) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    ::memcpy(p, b->start() + offset, bytes);
    p += bytes;
    len -= bytes;
    b = b->next;
    offset = 0;
  }

  return p;
}
<commit_msg>TS-3417: Add overlooked include back<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/**************************************************************************
  UIOBuffer.cc

**************************************************************************/
#include "ink_defs.h"
#include "P_EventSystem.h"

//
// General Buffer Allocator
//
inkcoreapi Allocator ioBufAllocator[DEFAULT_BUFFER_SIZES];
inkcoreapi ClassAllocator<MIOBuffer> ioAllocator("ioAllocator", DEFAULT_BUFFER_NUMBER);
inkcoreapi ClassAllocator<IOBufferData> ioDataAllocator("ioDataAllocator", DEFAULT_BUFFER_NUMBER);
inkcoreapi ClassAllocator<IOBufferBlock> ioBlockAllocator("ioBlockAllocator", DEFAULT_BUFFER_NUMBER);
int64_t default_large_iobuffer_size = DEFAULT_LARGE_BUFFER_SIZE;
int64_t default_small_iobuffer_size = DEFAULT_SMALL_BUFFER_SIZE;
int64_t max_iobuffer_size = DEFAULT_BUFFER_SIZES - 1;

//
// Initialization
//
void
init_buffer_allocators()
{
  char *name;
  int advice = 0;

#ifdef MADV_DONTDUMP // This should only exist on Linux 3.4 and higher.
  advice = MADV_DONTDUMP;
#endif

  for (int i = 0; i < DEFAULT_BUFFER_SIZES; i++) {
    int64_t s = DEFAULT_BUFFER_BASE_SIZE * (((int64_t)1) << i);
    int64_t a = DEFAULT_BUFFER_ALIGNMENT;
    int n = i <= default_large_iobuffer_size ? DEFAULT_BUFFER_NUMBER : DEFAULT_HUGE_BUFFER_NUMBER;
    if (s < a)
      a = s;

    name = new char[64];
    snprintf(name, 64, "ioBufAllocator[%d]", i);
    ioBufAllocator[i].re_init(name, s, n, a, advice);
  }
}

int64_t
MIOBuffer::remove_append(IOBufferReader * r)
{
  int64_t l = 0;
  while (r->block) {
    Ptr<IOBufferBlock> b = r->block;
    r->block = r->block->next;
    b->_start += r->start_offset;
    if (b->start() >= b->end()) {
      r->start_offset = -r->start_offset;
      continue;
    }
    r->start_offset = 0;
    l += b->read_avail();
    append_block(b);
  }
  r->mbuf->_writer = NULL;
  return l;
}

int64_t
MIOBuffer::write(const void *abuf, int64_t alen)
{
  const char *buf = (const char*)abuf;
  int64_t len = alen;
  while (len) {
    if (!_writer)
      add_block();
    int64_t f = _writer->write_avail();
    f = f < len ? f : len;
    if (f > 0) {
      ::memcpy(_writer->end(), buf, f);
      _writer->fill(f);
      buf += f;
      len -= f;
    }
    if (len) {
      if (!_writer->next)
        add_block();
      else
        _writer = _writer->next;
    }
  }
  return alen;
}

#ifdef WRITE_AND_TRANSFER
  /*
   * Same functionality as write but for the one small difference.
   * The space available in the last block is taken from the original
   * and this space becomes available to the copy.
   *
   */
int64_t
MIOBuffer::write_and_transfer_left_over_space(IOBufferReader * r, int64_t alen, int64_t offset)
{
  int64_t rval = write(r, alen, offset);
  // reset the end markers of the original so that it cannot
  // make use of the space in the current block
  if (r->mbuf->_writer)
    r->mbuf->_writer->_buf_end = r->mbuf->_writer->_end;
  // reset the end marker of the clone so that it can make
  // use of the space in the current block
  if (_writer) {
    _writer->_buf_end = _writer->data->data() + _writer->block_size();
  }
  return rval;
}

#endif

int64_t
MIOBuffer::write(IOBufferReader * r, int64_t alen, int64_t offset)
{
  int64_t len = alen;
  IOBufferBlock *b = r->block;
  offset += r->start_offset;

  while (b && len > 0) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    IOBufferBlock *bb = b->clone();
    bb->_start += offset;
    bb->_buf_end = bb->_end = bb->_start + bytes;
    append_block(bb);
    offset = 0;
    len -= bytes;
    b = b->next;
  }
  return alen - len;
}

int64_t
MIOBuffer::puts(char *s, int64_t len)
{
  char *pc = end();
  char *pb = s;
  while (pc < buf_end()) {
    if (len-- <= 0)
      return -1;
    if (!*pb || *pb == '\n') {
      int64_t n = (int64_t) (pb - s);
      memcpy(end(), s, n + 1);  // Upto and including '\n'
      end()[n + 1] = 0;
      fill(n + 1);
      return n + 1;
    }
    pc++;
    pb++;
  }
  return 0;
}

int64_t
IOBufferReader::read(void *ab, int64_t len)
{
  char *b = (char*)ab;
  int64_t max_bytes = read_avail();
  int64_t bytes = len <= max_bytes ? len : max_bytes;
  int64_t n = bytes;

  while (n) {
    int64_t l = block_read_avail();
    if (n < l)
      l = n;
    ::memcpy(b, start(), l);
    consume(l);
    b += l;
    n -= l;
  }
  return bytes;
}

// TODO: I don't think this method is used anywhere, so perhaps get rid of it ?
int64_t
IOBufferReader::memchr(char c, int64_t len, int64_t offset)
{
  IOBufferBlock *b = block;
  offset += start_offset;
  int64_t o = offset;

  while (b && len) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    char *s = b->start() + offset;
    char *p = (char *) ::memchr(s, c, bytes);
    if (p)
      return (int64_t) (o - start_offset + p - s);
    o += bytes;
    len -= bytes;
    b = b->next;
    offset = 0;
  }

  return -1;
}

char *
IOBufferReader::memcpy(const void *ap, int64_t len, int64_t offset)
{
  char *p = (char*)ap;
  IOBufferBlock *b = block;
  offset += start_offset;

  while (b && len) {
    int64_t max_bytes = b->read_avail();
    max_bytes -= offset;
    if (max_bytes <= 0) {
      offset = -max_bytes;
      b = b->next;
      continue;
    }
    int64_t bytes;
    if (len<0 || len>= max_bytes)
      bytes = max_bytes;
    else
      bytes = len;
    ::memcpy(p, b->start() + offset, bytes);
    p += bytes;
    len -= bytes;
    b = b->next;
    offset = 0;
  }

  return p;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ImageHistogram1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

// Software Guide : BeginLatex
//
// This example shows how to compute the histogram of a scalar image.  Since
// the classes of the Statistics framework operate on Samples and
// ListOfSamples, we need to introduce a class that will make the image look
// like a list of samples. This class is the \subdoxygen{Statistics}{ScalarImageToListAdaptor}.
// Once we have connected this adaptor to an image, we can proceed to use the
// \subdoxygen{Statistics}{ListSampleToHistogramGenerator} in order to compute the
// \subdoxygen{Statistics}{Histogram} of the image.
//
// First, we need to include the headers for the
// \subdoxygen{Statistics}{ScalarImageToListAdaptor} and the \doxygen{Image} classes.
//
// \index{itk::Statistics::ScalarImageToListAdaptor!header}
// \index{Statistics!Images}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkScalarImageToListAdaptor.h"
#include "itkImage.h"
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we include the headers for the \code{ListSampleToHistogramGenerator} and
// the reader that we will use for reading the image from a file.
//
// \index{itk::Statistics::ListSampleToHistogramGenerator!header}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkListSampleToHistogramGenerator.h"
// Software Guide : EndCodeSnippet

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

  if( argc < 2 )
    {
    std::cerr << "Missing command line arguments" << std::endl;
    std::cerr << "Usage :  ImageHistogram1  inputImageFileName " << std::endl;
    return -1;
    }

// Software Guide : BeginLatex
//
// The image type must be defined using the typical pair of pixel type and
// dimension specification.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned char       PixelType;
  const unsigned int          Dimension = 2;

  typedef itk::Image<PixelType, Dimension > ImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Using the same image type we instantiate the type of the image reader that
// will provide the image source for our example.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< ImageType > ReaderType;

  ReaderType::Pointer reader = ReaderType::New();

  reader->SetFileName( argv[1] );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we introduce the central piece of this example, which is the use of the
// adaptor that will present the \doxygen{Image} as if it was a list of
// samples. We instantiate the type of the adaptor by using the actual image
// type. Then construct the adaptor by invoking its \code{New()} method and
// assigning the result to the corresponding smart pointer. Finally we connect
// the output of the image reader to the input of the adaptor.
//
// \index{itk::Statistics::ScalarImageToListAdaptor!instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::Statistics::ScalarImageToListAdaptor< ImageType >   AdaptorType;

  AdaptorType::Pointer adaptor = AdaptorType::New();

  adaptor->SetImage(  reader->GetOutput() );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// You must keep in mind that adaptors are not pipeline objects. This means
// that they do not propagate update calls. It is therefore your responsibility
// to make sure that you invoke the \code{Update()} method of the reader before
// you attempt to use the output of the adaptor. As usual, this must be done
// inside a try/catch block because the read operation can potentially throw
// exceptions.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Problem reading image file : " << argv[1] << std::endl;
    std::cerr << excp << std::endl;
    return -1;
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// At this point, we are ready for instantiating the type of the histogram
// generator. Note that the adaptor type is used as template parameter of the
// generator. Having instantiated this type, we proceed to create one generator
// by invoking its \code{New()} method.
//
// \index{itk::Statistics::ListSampleToHistogramGenerator!instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef PixelType        HistogramMeasurementType;

  typedef itk::Statistics::ListSampleToHistogramGenerator<
                                                AdaptorType,
                                                HistogramMeasurementType
                                                                > GeneratorType;

  GeneratorType::Pointer generator = GeneratorType::New();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We define now the characteristics of the Histogram that we want to compute.
// This typically includes the size of each one of the component, but given
// that in this simple example we are dealing with a scalar image, then our
// histogram will have a single component. For the sake of generality, however,
// we use the \code{HistogramType} as defined inside of the Generator type. We
// define also the marginal scale factor that will control the precision used
// when assigning values to histogram bines. Finally we invoke the
// \code{Update()} method in the generator.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef GeneratorType::HistogramType  HistogramType;

  HistogramType::SizeType size;
  size.Fill( 255 );

  generator->SetListSample( adaptor );
  generator->SetNumberOfBins( size );
  generator->SetMarginalScale( 10.0 );

  generator->Update();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we are ready for using the image histogram for any further processing.
// The histogram is obtained from the generator by invoking the
// \code{GetOutput()} method.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  HistogramType::ConstPointer histogram = generator->GetOutput();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// In this current example we simply print out the frequency values of all the
// bins in the image histogram.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const unsigned int histogramSize = histogram->Size();

  std::cout << "Histogram size " << histogramSize << std::endl;

  for( unsigned int bin=0; bin < histogramSize; bin++ )
    {
    std::cout << "bin = " << bin << " frequency = ";
    std::cout << histogram->GetFrequency( bin, 0 ) <<std::endl;
    }
// Software Guide : EndCodeSnippet

  return 0;

}

<commit_msg>STYLE: Minor typos on Software Guide comments.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ImageHistogram1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

// Software Guide : BeginLatex
//
// This example shows how to compute the histogram of a scalar image.  Since
// the classes of the Statistics framework operate on Samples and
// ListOfSamples, we need to introduce a class that will make the image look
// like a list of samples. This class is the
// \subdoxygen{Statistics}{ScalarImageToListAdaptor}.  Once we have connected
// this adaptor to an image, we can proceed to use the
// \subdoxygen{Statistics}{ListSampleToHistogramGenerator} in order to compute
// the histogram of the image.
//
// First, we need to include the headers for the
// \subdoxygen{Statistics}{ScalarImageToListAdaptor} and the \doxygen{Image} classes.
//
// \index{itk::Statistics::ScalarImageToListAdaptor!header}
// \index{Statistics!Images}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkScalarImageToListAdaptor.h"
#include "itkImage.h"
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we include the headers for the \code{ListSampleToHistogramGenerator} and
// the reader that we will use for reading the image from a file.
//
// \index{itk::Statistics::ListSampleToHistogramGenerator!header}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkImageFileReader.h"
#include "itkListSampleToHistogramGenerator.h"
// Software Guide : EndCodeSnippet

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

  if( argc < 2 )
    {
    std::cerr << "Missing command line arguments" << std::endl;
    std::cerr << "Usage :  ImageHistogram1  inputImageFileName " << std::endl;
    return -1;
    }

// Software Guide : BeginLatex
//
// The image type must be defined using the typical pair of pixel type and
// dimension specification.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef unsigned char       PixelType;
  const unsigned int          Dimension = 2;

  typedef itk::Image<PixelType, Dimension > ImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Using the same image type we instantiate the type of the image reader that
// will provide the image source for our example.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< ImageType > ReaderType;

  ReaderType::Pointer reader = ReaderType::New();

  reader->SetFileName( argv[1] );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we introduce the central piece of this example, which is the use of the
// adaptor that will present the \doxygen{Image} as if it was a list of
// samples. We instantiate the type of the adaptor by using the actual image
// type. Then construct the adaptor by invoking its \code{New()} method and
// assigning the result to the corresponding smart pointer. Finally we connect
// the output of the image reader to the input of the adaptor.
//
// \index{itk::Statistics::ScalarImageToListAdaptor!instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::Statistics::ScalarImageToListAdaptor< ImageType >   AdaptorType;

  AdaptorType::Pointer adaptor = AdaptorType::New();

  adaptor->SetImage(  reader->GetOutput() );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// You must keep in mind that adaptors are not pipeline objects. This means
// that they do not propagate update calls. It is therefore your responsibility
// to make sure that you invoke the \code{Update()} method of the reader before
// you attempt to use the output of the adaptor. As usual, this must be done
// inside a try/catch block because the read operation can potentially throw
// exceptions.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Problem reading image file : " << argv[1] << std::endl;
    std::cerr << excp << std::endl;
    return -1;
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// At this point, we are ready for instantiating the type of the histogram
// generator. Note that the adaptor type is used as template parameter of the
// generator. Having instantiated this type, we proceed to create one generator
// by invoking its \code{New()} method.
//
// \index{itk::Statistics::ListSampleToHistogramGenerator!instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef PixelType        HistogramMeasurementType;

  typedef itk::Statistics::ListSampleToHistogramGenerator<
                                                AdaptorType,
                                                HistogramMeasurementType
                                                                > GeneratorType;

  GeneratorType::Pointer generator = GeneratorType::New();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// We define now the characteristics of the Histogram that we want to compute.
// This typically includes the size of each one of the component, but given
// that in this simple example we are dealing with a scalar image, then our
// histogram will have a single component. For the sake of generality, however,
// we use the \code{HistogramType} as defined inside of the Generator type. We
// define also the marginal scale factor that will control the precision used
// when assigning values to histogram bins. Finally we invoke the
// \code{Update()} method in the generator.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef GeneratorType::HistogramType  HistogramType;

  HistogramType::SizeType size;
  size.Fill( 255 );

  generator->SetListSample( adaptor );
  generator->SetNumberOfBins( size );
  generator->SetMarginalScale( 10.0 );

  generator->Update();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Now we are ready for using the image histogram for any further processing.
// The histogram is obtained from the generator by invoking the
// \code{GetOutput()} method.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  HistogramType::ConstPointer histogram = generator->GetOutput();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// In this current example we simply print out the frequency values of all the
// bins in the image histogram.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const unsigned int histogramSize = histogram->Size();

  std::cout << "Histogram size " << histogramSize << std::endl;

  for( unsigned int bin=0; bin < histogramSize; bin++ )
    {
    std::cout << "bin = " << bin << " frequency = ";
    std::cout << histogram->GetFrequency( bin, 0 ) <<std::endl;
    }
// Software Guide : EndCodeSnippet

  return 0;

}

<|endoftext|>


<commit_before>// -*- Mode: c++-mode; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 2; -*-
//
// Copyright (C) 2003 Grzegorz Jaskiewicz 	<gj at pointblue.com.pl>
//
// gaduregisteraccount.cpp
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.

#include <qstring.h>
#include <qregexp.h>
#include <qpushbutton.h>
#include <qlabel.h>

#include <klineedit.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kglobal.h>

#include "gaduregisteraccountui.h"
#include "gaduregisteraccount.h"
#include "gaducommands.h"

GaduRegisterAccount::GaduRegisterAccount( QWidget* parent, const char* name )
: KDialogBase( parent, name, true, i18n( "Register New Account" ), KDialogBase::User1 | KDialogBase::Ok, KDialogBase::User1, true )
{
	ui = new GaduRegisterAccountUI( this );
	setMainWidget( ui );

	ui->valueVerificationSequence->setDisabled( true );
	setButtonText( User1, i18n( "&Register" ) );
	setButtonText( Ok, i18n( "&Cancel" ) );
	enableButton( User1, false );

	cRegister = new RegisterCommand( this );

	emailRegexp = new QRegExp(  "[\\w\\d.+_-]{1,}@[\\w\\d.-]{1,}" );
	hintPixmap = KGlobal::iconLoader()->loadIcon ( "gadu_protocol", KIcon::Small );

	connect( this, SIGNAL( user1Clicked() ), SLOT( doRegister() ) );
	connect( this, SIGNAL( okClicked() ), SLOT( slotClose() ) );

	connect( ui->valueEmailAddress, SIGNAL( textChanged( const QString &) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valuePassword, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valuePasswordVerify, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valueVerificationSequence, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );

	connect( cRegister, SIGNAL( tokenRecieved( QPixmap, QString ) ), SLOT( displayToken( QPixmap, QString ) ) );
	connect( cRegister, SIGNAL( done(  const QString&,  const QString& ) ), SLOT( registrationDone(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( error(  const QString&,  const QString& ) ), SLOT( registrationError(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( operationStatus( const QString ) ), SLOT( updateStatus( const QString ) ) );

	updateStatus( i18n( "Retrieving token" ) );
	cRegister->requestToken();

	show();
}

void
GaduRegisterAccount::doRegister( )
{
	cRegister->setUserinfo( ui->valueEmailAddress->text(), ui->valuePassword->text(), ui->valueVerificationSequence->text() );
	cRegister->execute();
	enableButton( User1, false );
}

void
GaduRegisterAccount::validateInput()
{
	int valid = true;
	int passwordHighlight = false;

	if ( !emailRegexp->exactMatch( ui->valueEmailAddress->text() ) )
	{
		updateStatus( i18n( "Please enter a valid E-Mail Address." ) );
		ui->pixmapEmailAddress->setPixmap ( hintPixmap );
		valid = false;
	}
	else {
		ui->pixmapEmailAddress->setText ( "" );
	}

	if ( valid && ( ( ui->valuePassword->text().isEmpty() ) || ( ui->valuePasswordVerify->text().isEmpty() ) ) )
	{
		updateStatus( i18n( "Please enter the same password twice." ) );
		valid = false;
		passwordHighlight = true;
	}

	if ( valid && ( ui->valuePassword->text() != ui->valuePasswordVerify->text() ) )
	{
		updateStatus( i18n( "Password entries do not match." ) );
		valid = false;
		passwordHighlight = true;
	}

	if ( valid && ( ui->valueVerificationSequence->text().isEmpty() ) )
	{
		updateStatus( i18n( "Please enter the verification sequence." ) );
		ui->pixmapVerificationSequence->setPixmap ( hintPixmap );
		valid = false;
	}
	else {
		ui->pixmapVerificationSequence->setText ( "" );
	}

	if ( passwordHighlight == true )
	{
		ui->pixmapPassword->setPixmap ( hintPixmap );
		ui->pixmapPasswordVerify->setPixmap ( hintPixmap );
	}
	else {
		ui->pixmapPassword->setText ( "" );
		ui->pixmapPasswordVerify->setText ( "" );
	}

	if ( valid )
	{
		// clear status message if we have valid data
		updateStatus( i18n( "" ) );
	}

	enableButton( User1, valid );
}

void
GaduRegisterAccount::inputChanged( const QString & )
{
	validateInput();
}

void
GaduRegisterAccount::registrationDone(  const QString& /*title*/,  const QString& /*what */ )
{
	ui->valueEmailAddress->setDisabled( true );
	ui->valuePassword->setDisabled( true );
	ui->valuePasswordVerify->setDisabled( true );
	ui->valueVerificationSequence->setDisabled( true );
	ui->labelEmailAddress->setDisabled( true );
	ui->labelPassword->setDisabled( true );
	ui->labelPasswordVerify->setDisabled( true );
	ui->labelVerificationSequence->setDisabled( true );
	ui->labelInstructions->setDisabled( true );
	emit registeredNumber( cRegister->newUin(), ui->valuePassword->text() );
	updateStatus( i18n( "Account created; your new UIN is %1." ).arg(QString::number( cRegister->newUin() )  ) );
	enableButton( User1, false );
	setButtonText( Ok, i18n( "&Close" ) );
}

void
GaduRegisterAccount::registrationError(  const QString& title,  const QString& what )
{
	updateStatus( i18n( "Registration failed: %1" ).arg( what ) );
	KMessageBox::sorry( this, what, title );

	disconnect( this, SLOT( displayToken( QPixmap, QString ) ) );
	disconnect( this, SLOT( registrationDone(  const QString&,  const QString& ) ) );
	disconnect( this, SLOT( registrationError(  const QString&,  const QString& ) ) );
	disconnect( this, SLOT( updateStatus( const QString ) ) );

// it is set to deleteLater, in case of error
	cRegister = NULL;
	ui->valueVerificationSequence->setDisabled( true );
	ui->valueVerificationSequence->setText( "" );
	enableButton( User1, false );
	updateStatus( "" );

	cRegister = new RegisterCommand( this );

	connect( cRegister, SIGNAL( tokenRecieved( QPixmap, QString ) ), SLOT( displayToken( QPixmap, QString ) ) );
	connect( cRegister, SIGNAL( done(  const QString&,  const QString& ) ), SLOT( registrationDone(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( error(  const QString&,  const QString& ) ), SLOT( registrationError(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( operationStatus( const QString ) ), SLOT( updateStatus( const QString ) ) );

	updateStatus( i18n( "Retrieving token" ) );
	cRegister->requestToken();
}

void
GaduRegisterAccount::displayToken( QPixmap image, QString /*tokenId */ )
{
	ui->valueVerificationSequence->setDisabled( false );
	ui->pixmapToken->setPixmap( image );
	validateInput();
}

void
GaduRegisterAccount::updateStatus( const QString status )
{
	ui->labelStatusMessage->setAlignment( AlignCenter );
	ui->labelStatusMessage->setText( status );
}

void
GaduRegisterAccount::slotClose()
{
	delete cRegister;
	cRegister = NULL;
}

GaduRegisterAccount::~GaduRegisterAccount( )
{
	kdDebug( 14100 ) << " register Cancel " << endl;
	delete cRegister;
	cRegister = NULL;
}

#include "gaduregisteraccount.moc"
<commit_msg>CVS_SILENT:infact there is no need to assign NULL in destructor<commit_after>// -*- Mode: c++-mode; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 2; -*-
//
// Copyright (C) 2003 Grzegorz Jaskiewicz 	<gj at pointblue.com.pl>
//
// gaduregisteraccount.cpp
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.

#include <qstring.h>
#include <qregexp.h>
#include <qpushbutton.h>
#include <qlabel.h>

#include <klineedit.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kglobal.h>

#include "gaduregisteraccountui.h"
#include "gaduregisteraccount.h"
#include "gaducommands.h"

GaduRegisterAccount::GaduRegisterAccount( QWidget* parent, const char* name )
: KDialogBase( parent, name, true, i18n( "Register New Account" ), KDialogBase::User1 | KDialogBase::Ok, KDialogBase::User1, true )
{
	ui = new GaduRegisterAccountUI( this );
	setMainWidget( ui );

	ui->valueVerificationSequence->setDisabled( true );
	setButtonText( User1, i18n( "&Register" ) );
	setButtonText( Ok, i18n( "&Cancel" ) );
	enableButton( User1, false );

	cRegister = new RegisterCommand( this );

	emailRegexp = new QRegExp(  "[\\w\\d.+_-]{1,}@[\\w\\d.-]{1,}" );
	hintPixmap = KGlobal::iconLoader()->loadIcon ( "gadu_protocol", KIcon::Small );

	connect( this, SIGNAL( user1Clicked() ), SLOT( doRegister() ) );
	connect( this, SIGNAL( okClicked() ), SLOT( slotClose() ) );

	connect( ui->valueEmailAddress, SIGNAL( textChanged( const QString &) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valuePassword, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valuePasswordVerify, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );
	connect( ui->valueVerificationSequence, SIGNAL( textChanged( const QString & ) ), SLOT( inputChanged( const QString & ) ) );

	connect( cRegister, SIGNAL( tokenRecieved( QPixmap, QString ) ), SLOT( displayToken( QPixmap, QString ) ) );
	connect( cRegister, SIGNAL( done(  const QString&,  const QString& ) ), SLOT( registrationDone(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( error(  const QString&,  const QString& ) ), SLOT( registrationError(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( operationStatus( const QString ) ), SLOT( updateStatus( const QString ) ) );

	updateStatus( i18n( "Retrieving token" ) );
	cRegister->requestToken();

	show();
}

void
GaduRegisterAccount::doRegister( )
{
	cRegister->setUserinfo( ui->valueEmailAddress->text(), ui->valuePassword->text(), ui->valueVerificationSequence->text() );
	cRegister->execute();
	enableButton( User1, false );
}

void
GaduRegisterAccount::validateInput()
{
	int valid = true;
	int passwordHighlight = false;

	if ( !emailRegexp->exactMatch( ui->valueEmailAddress->text() ) )
	{
		updateStatus( i18n( "Please enter a valid E-Mail Address." ) );
		ui->pixmapEmailAddress->setPixmap ( hintPixmap );
		valid = false;
	}
	else {
		ui->pixmapEmailAddress->setText ( "" );
	}

	if ( valid && ( ( ui->valuePassword->text().isEmpty() ) || ( ui->valuePasswordVerify->text().isEmpty() ) ) )
	{
		updateStatus( i18n( "Please enter the same password twice." ) );
		valid = false;
		passwordHighlight = true;
	}

	if ( valid && ( ui->valuePassword->text() != ui->valuePasswordVerify->text() ) )
	{
		updateStatus( i18n( "Password entries do not match." ) );
		valid = false;
		passwordHighlight = true;
	}

	if ( valid && ( ui->valueVerificationSequence->text().isEmpty() ) )
	{
		updateStatus( i18n( "Please enter the verification sequence." ) );
		ui->pixmapVerificationSequence->setPixmap ( hintPixmap );
		valid = false;
	}
	else {
		ui->pixmapVerificationSequence->setText ( "" );
	}

	if ( passwordHighlight == true )
	{
		ui->pixmapPassword->setPixmap ( hintPixmap );
		ui->pixmapPasswordVerify->setPixmap ( hintPixmap );
	}
	else {
		ui->pixmapPassword->setText ( "" );
		ui->pixmapPasswordVerify->setText ( "" );
	}

	if ( valid )
	{
		// clear status message if we have valid data
		updateStatus( i18n( "" ) );
	}

	enableButton( User1, valid );
}

void
GaduRegisterAccount::inputChanged( const QString & )
{
	validateInput();
}

void
GaduRegisterAccount::registrationDone(  const QString& /*title*/,  const QString& /*what */ )
{
	ui->valueEmailAddress->setDisabled( true );
	ui->valuePassword->setDisabled( true );
	ui->valuePasswordVerify->setDisabled( true );
	ui->valueVerificationSequence->setDisabled( true );
	ui->labelEmailAddress->setDisabled( true );
	ui->labelPassword->setDisabled( true );
	ui->labelPasswordVerify->setDisabled( true );
	ui->labelVerificationSequence->setDisabled( true );
	ui->labelInstructions->setDisabled( true );
	emit registeredNumber( cRegister->newUin(), ui->valuePassword->text() );
	updateStatus( i18n( "Account created; your new UIN is %1." ).arg(QString::number( cRegister->newUin() )  ) );
	enableButton( User1, false );
	setButtonText( Ok, i18n( "&Close" ) );
}

void
GaduRegisterAccount::registrationError(  const QString& title,  const QString& what )
{
	updateStatus( i18n( "Registration failed: %1" ).arg( what ) );
	KMessageBox::sorry( this, what, title );

	disconnect( this, SLOT( displayToken( QPixmap, QString ) ) );
	disconnect( this, SLOT( registrationDone(  const QString&,  const QString& ) ) );
	disconnect( this, SLOT( registrationError(  const QString&,  const QString& ) ) );
	disconnect( this, SLOT( updateStatus( const QString ) ) );

// it is set to deleteLater, in case of error
	cRegister = NULL;
	ui->valueVerificationSequence->setDisabled( true );
	ui->valueVerificationSequence->setText( "" );
	enableButton( User1, false );
	updateStatus( "" );

	cRegister = new RegisterCommand( this );

	connect( cRegister, SIGNAL( tokenRecieved( QPixmap, QString ) ), SLOT( displayToken( QPixmap, QString ) ) );
	connect( cRegister, SIGNAL( done(  const QString&,  const QString& ) ), SLOT( registrationDone(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( error(  const QString&,  const QString& ) ), SLOT( registrationError(  const QString&,  const QString& ) ) );
	connect( cRegister, SIGNAL( operationStatus( const QString ) ), SLOT( updateStatus( const QString ) ) );

	updateStatus( i18n( "Retrieving token" ) );
	cRegister->requestToken();
}

void
GaduRegisterAccount::displayToken( QPixmap image, QString /*tokenId */ )
{
	ui->valueVerificationSequence->setDisabled( false );
	ui->pixmapToken->setPixmap( image );
	validateInput();
}

void
GaduRegisterAccount::updateStatus( const QString status )
{
	ui->labelStatusMessage->setAlignment( AlignCenter );
	ui->labelStatusMessage->setText( status );
}

void
GaduRegisterAccount::slotClose()
{
	delete cRegister;
	cRegister = NULL;
}

GaduRegisterAccount::~GaduRegisterAccount( )
{
	kdDebug( 14100 ) << " register Cancel " << endl;
	delete cRegister;
}

#include "gaduregisteraccount.moc"
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include <algorithm>
#include <cinttypes>
#include <cmath>
#include <cstdlib>
#include <random>
#include <string>

#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/all_close.hpp"
#include "util/all_close_f.hpp"
#include "util/ndarray.hpp"
#include "util/test_control.hpp"
#include "util/test_tools.hpp"

using namespace std;
using namespace ngraph;

static string s_manifest = "${MANIFEST}";

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_2_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{0, 0, 1}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_1_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{1});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{0, 1, 0}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_0_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{1, 0, 0}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_fp_nonint_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{1.1f});
    auto result = backend->create_tensor(element::f32, shape_r);

    try
    {
        auto handle = backend->compile(f);
        handle->call_with_validate({result}, {a});
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(e.what(), std::string("One-hot: non-integral value in input"));
    }
    catch (...)
    {
        FAIL() << "Expected a std::out_of_range exception";
    }
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_oob_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{3});
    vector<int32_t> r_data(4);
    auto result = backend->create_tensor(element::i32, shape_r, r_data.data());

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(r_data[3], 0);
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_0)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3, 8};
    auto r = make_shared<op::OneHot>(A, Shape{3, 8}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<int32_t>{0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0}),
        read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<int32_t>{0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}),
        read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_barely_oob)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 3, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    vector<int32_t> rv = read_vector<int32_t>(result);

    EXPECT_EQ(rv[0], 0);
    EXPECT_EQ(rv[1], 0);
    EXPECT_EQ(rv[2], 1);

    EXPECT_EQ(rv[3], 0);
    EXPECT_EQ(rv[4], 1);
    EXPECT_EQ(rv[5], 0);

    EXPECT_EQ(rv[6], 1);
    EXPECT_EQ(rv[7], 0);
    EXPECT_EQ(rv[8], 0);

    EXPECT_EQ(rv[9], 1);
    EXPECT_EQ(rv[10], 0);
    EXPECT_EQ(rv[11], 0);

    // These are undefined since value is out of bounds
    // EXPECT_EQ(rv[12], 0);
    // EXPECT_EQ(rv[13], 0);
    // EXPECT_EQ(rv[14], 0);

    EXPECT_EQ(rv[15], 0);
    EXPECT_EQ(rv[16], 0);
    EXPECT_EQ(rv[17], 1);

    EXPECT_EQ(rv[18], 0);
    EXPECT_EQ(rv[19], 1);
    EXPECT_EQ(rv[20], 0);

    EXPECT_EQ(rv[21], 1);
    EXPECT_EQ(rv[22], 0);
    EXPECT_EQ(rv[23], 0);
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_matrix_0)
{
    Shape shape_a{3, 3};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3, 3, 3};
    auto r = make_shared<op::OneHot>(A, Shape{3, 3, 3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a,
              vector<int32_t>{
                  0, 1, 1, 2, 1, 0, 0, 2, 1,
              });
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{1, 0, 0, 0, 0, 1, 1, 0, 0,

                               0, 1, 1, 0, 1, 0, 0, 0, 1,

                               0, 0, 0, 1, 0, 0, 0, 1, 0}),
              read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_fp)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::f32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<float>{0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}),
        read_vector<float>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_fp_nonint)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{2, 1, 0, 0, 2, 2, 1.01f, 0});
    auto result = backend->create_tensor(element::f32, shape_r);

    try
    {
        auto handle = backend->compile(f);
        handle->call_with_validate({result}, {a});
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(e.what(), std::string("One-hot: non-integral value in input"));
    }
    catch (...)
    {
        FAIL() << "Expected a std::out_of_range exception";
    }
}
<commit_msg>Add a new onehot unit test (#2670)<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//*****************************************************************************

#include <algorithm>
#include <cinttypes>
#include <cmath>
#include <cstdlib>
#include <random>
#include <string>

#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/all_close.hpp"
#include "util/all_close_f.hpp"
#include "util/ndarray.hpp"
#include "util/test_control.hpp"
#include "util/test_tools.hpp"

using namespace std;
using namespace ngraph;

static string s_manifest = "${MANIFEST}";

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_2_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{0, 0, 1}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_1_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{1});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{0, 1, 0}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_0_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{1, 0, 0}), read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_fp_nonint_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{1.1f});
    auto result = backend->create_tensor(element::f32, shape_r);

    try
    {
        auto handle = backend->compile(f);
        handle->call_with_validate({result}, {a});
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(e.what(), std::string("One-hot: non-integral value in input"));
    }
    catch (...)
    {
        FAIL() << "Expected a std::out_of_range exception";
    }
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_scalar_oob_in_3)
{
    Shape shape_a{};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3};
    auto r = make_shared<op::OneHot>(A, Shape{3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{3});
    vector<int32_t> r_data(4);
    auto result = backend->create_tensor(element::i32, shape_r, r_data.data());

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(r_data[3], 0);
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_0)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3, 8};
    auto r = make_shared<op::OneHot>(A, Shape{3, 8}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<int32_t>{0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0}),
        read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<int32_t>{0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}),
        read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_barely_oob)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a, vector<int32_t>{2, 1, 0, 0, 3, 2, 1, 0});
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    vector<int32_t> rv = read_vector<int32_t>(result);

    EXPECT_EQ(rv[0], 0);
    EXPECT_EQ(rv[1], 0);
    EXPECT_EQ(rv[2], 1);

    EXPECT_EQ(rv[3], 0);
    EXPECT_EQ(rv[4], 1);
    EXPECT_EQ(rv[5], 0);

    EXPECT_EQ(rv[6], 1);
    EXPECT_EQ(rv[7], 0);
    EXPECT_EQ(rv[8], 0);

    EXPECT_EQ(rv[9], 1);
    EXPECT_EQ(rv[10], 0);
    EXPECT_EQ(rv[11], 0);

    // These are undefined since value is out of bounds
    // EXPECT_EQ(rv[12], 0);
    // EXPECT_EQ(rv[13], 0);
    // EXPECT_EQ(rv[14], 0);

    EXPECT_EQ(rv[15], 0);
    EXPECT_EQ(rv[16], 0);
    EXPECT_EQ(rv[17], 1);

    EXPECT_EQ(rv[18], 0);
    EXPECT_EQ(rv[19], 1);
    EXPECT_EQ(rv[20], 0);

    EXPECT_EQ(rv[21], 1);
    EXPECT_EQ(rv[22], 0);
    EXPECT_EQ(rv[23], 0);
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_matrix_0)
{
    Shape shape_a{3, 3};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{3, 3, 3};
    auto r = make_shared<op::OneHot>(A, Shape{3, 3, 3}, 0);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    copy_data(a,
              vector<int32_t>{
                  0, 1, 1, 2, 1, 0, 0, 2, 1,
              });
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ((vector<int32_t>{1, 0, 0, 0, 0, 1, 1, 0, 0,

                               0, 1, 1, 0, 1, 0, 0, 0, 1,

                               0, 0, 0, 1, 0, 0, 0, 1, 0}),
              read_vector<int32_t>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_fp)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{2, 1, 0, 0, 2, 2, 1, 0});
    auto result = backend->create_tensor(element::f32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    EXPECT_EQ(
        (vector<float>{0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}),
        read_vector<float>(result));
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_1_fp_nonint)
{
    Shape shape_a{8};
    auto A = make_shared<op::Parameter>(element::f32, shape_a);
    Shape shape_r{8, 3};
    auto r = make_shared<op::OneHot>(A, Shape{8, 3}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::f32, shape_a);
    copy_data(a, vector<float>{2, 1, 0, 0, 2, 2, 1.01f, 0});
    auto result = backend->create_tensor(element::f32, shape_r);

    try
    {
        auto handle = backend->compile(f);
        handle->call_with_validate({result}, {a});
    }
    catch (const std::exception& e)
    {
        EXPECT_EQ(e.what(), std::string("One-hot: non-integral value in input"));
    }
    catch (...)
    {
        FAIL() << "Expected a std::out_of_range exception";
    }
}

NGRAPH_TEST(${BACKEND_NAME}, one_hot_vector_many_categories)
{
    // Imagenet has roughly 20,000 categories
    uint32_t category_count = 20000;
    Shape shape_a{6};
    auto A = make_shared<op::Parameter>(element::i32, shape_a);
    Shape shape_r{6, category_count};
    auto r = make_shared<op::OneHot>(A, Shape{6, category_count}, 1);
    auto f = make_shared<Function>(r, ParameterVector{A});

    auto backend = runtime::Backend::create("${BACKEND_NAME}");

    // Create some tensors for input/output
    auto a = backend->create_tensor(element::i32, shape_a);
    vector<int32_t> input_data{0, 11, 101, 1001, 10001, static_cast<int32_t>(category_count - 1)};
    copy_data(a, input_data);
    auto result = backend->create_tensor(element::i32, shape_r);

    auto handle = backend->compile(f);
    handle->call_with_validate({result}, {a});
    vector<int32_t> data = read_vector<int32_t>(result);

    vector<int32_t> bit_positions;
    for (size_t i = 0; i < shape_size(shape_r); ++i)
    {
        if (data[i] == 1)
        {
            bit_positions.push_back(i % category_count);
        }
    }
    EXPECT_EQ(bit_positions, input_data);
}
<|endoftext|>


<commit_before>/*
    oscarstatusmanager.cpp  -  Oscar status manager

    Copyright (c) 2004      by Richard Smith          <kde@metafoo.co.uk>
    Copyright (c) 2006,2007 by Roman Jarosz           <kedgedev@centrum.cz>
    Kopete    (c) 2002-2007 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "oscarstatusmanager.h"

#include <QHash>

#include <kdebug.h>

#include "oscarprotocol.h"
#include "oscarpresencesdataclasses.h"

class OscarStatusManager::Private
{
public:
	OscarProtocol* protocol;

	typedef QHash<int, Kopete::OnlineStatus> StatusHash;
	StatusHash statusHash;

	QList<Oscar::PresenceType> presenceTypeList;
	QList<Oscar::PresenceOverlay> presenceOverlayList;

	Oscar::Presence::Flags mask;
};

OscarStatusManager::OscarStatusManager( OscarProtocol* protocol )
	: d( new Private() )
{
	d->protocol = protocol;
	d->mask = ~(Oscar::Presence::Flags)Oscar::Presence::None;
}

OscarStatusManager::~OscarStatusManager()
{
	delete d;
}

void OscarStatusManager::initialize( uint firstUsableWeight )
{
	for ( uint i = 0; i < Oscar::Presence::TypeCount; ++i )
	{
		const Oscar::PresenceType &data =  pscTypeForType( static_cast<Oscar::Presence::Type>(i) );
		const uint weight = i + firstUsableWeight;
		for ( int j = 0; j < data.overlayFlagsList().count(); ++j )
		{
			const uint internalStatus = data.overlayFlagsList().at(j) | data.type();

			Kopete::OnlineStatus status;
			if ( data.overlayFlagsList().at(j) != Oscar::Presence::None )
			{
				Oscar::PresenceOverlay overlay = pscOverlayForFlags( data.overlayFlagsList().at(j) );
				//don't add KOS to account's context menu
				status = Kopete::OnlineStatus( data.onlineStatusType(), weight,
				                               d->protocol, internalStatus,
				                               data.overlayIcons() + overlay.icons(),
				                               data.name() + QString(" (%1)").arg( overlay.description() ) );
			}
			else
			{
				//add KOS
				status = Kopete::OnlineStatus( data.onlineStatusType(), weight,
				                               d->protocol, internalStatus,
				                               data.overlayIcons(), data.name(),
				                               data.caption(), data.categories(), data.options() );
			}
			d->statusHash[internalStatus] = status;
		}
	}
}

void OscarStatusManager::setPresenceType( const QList<Oscar::PresenceType>& list )
{
	d->presenceTypeList = list;
}

void OscarStatusManager::setPresenceOverlay( const QList<Oscar::PresenceOverlay>& list )
{
	d->presenceOverlayList = list;
}

void OscarStatusManager::setPresenceFlagsMask( Oscar::Presence::Flags mask )
{
	d->mask = mask;
}

Kopete::OnlineStatus OscarStatusManager::onlineStatusOf( const Oscar::Presence &presence ) const
{
	Oscar::Presence pres( presence.internalStatus() & d->mask );
	pres.setDescription( presence.description() );

	if ( (pres.flags() & Oscar::Presence::XStatus) == Oscar::Presence::XStatus )
	{
		kDebug() << "Creating Kopete::OnlineStatus for XStatus, internal status: " << pres.internalStatus();
		// XStatus, we have to create new KOS
		Oscar::PresenceOverlay overlay = pscOverlayForFlags( pres.flags() );

		QString desc = kosDescription( pres );
		QString xtrazIcon = QString( "icq_xstatus%1" ).arg( pres.xtrazStatus() );
		return Kopete::OnlineStatus( Kopete::OnlineStatus::Online, 0, d->protocol, pres.internalStatus(),
		                             QStringList( xtrazIcon ) + overlay.icons(), desc );
	}
	else if ( (pres.flags() & Oscar::Presence::ExtStatus) == Oscar::Presence::ExtStatus )
	{
		kDebug() << "Creating Kopete::OnlineStatus for ExtStatus, internal status: " << pres.internalStatus();
		// ExtStatus, we have to create new KOS
		Oscar::PresenceOverlay overlay = pscOverlayForFlags( pres.flags() );
		const Oscar::PresenceType &type = pscTypeForType( pres.type() );

		QString desc = kosDescription( pres );
		return Kopete::OnlineStatus( type.onlineStatusType(), 0, d->protocol, pres.internalStatus(),
		                             type.overlayIcons() + overlay.icons(), desc );
	}
	else
	{
		if ( d->statusHash.contains( pres.internalStatus() ) )
		{
			return d->statusHash.value( pres.internalStatus() );
		}
		else if ( d->statusHash.contains( pres.type() ) )
		{
			kWarning() << "Kopete::OnlineStatus doesn't exists for internal status " << pres.internalStatus()
			           << " Using basic status for type " << pres.type() << endl;
			return d->statusHash.value( pres.type() );
		}
		else
		{
			kWarning() << "Kopete::OnlineStatus doesn't exists for internal status " << pres.internalStatus();
			return unknownStatus();
		}
	}
}

Oscar::Presence OscarStatusManager::presenceOf( const Kopete::OnlineStatus &status ) const
{
	if ( status.protocol() == d->protocol )
	{
		Oscar::Presence presence( status.internalStatus() );
		if ( (presence.flags() & Oscar::Presence::XStatus) || (presence.flags() & Oscar::Presence::ExtStatus) )
		{
			// ExtStatus/XStatus, we have to filter out description
			presence.setDescription( descriptionFromKOS( status ) );
		}
		return presence;
	}
	else
	{
		//status is a libkopete builtin status object
		//don't even think about converting it to Oscar::Presence using presenceOf!
		return Oscar::Presence( pscTypeForOnlineStatusType( status.status() ).type(),
		                        Oscar::Presence::None );
	}
}

unsigned long OscarStatusManager::oscarStatusOf( const Oscar::Presence &presence ) const
{
	unsigned long basicStatus = basicOscarStatus( presence.type() );
	if ( (presence.internalStatus() & Oscar::Presence::Invisible) == Oscar::Presence::Invisible )
		basicStatus |= Oscar::StatusCode::INVISIBLE;
	return basicStatus;
}

Oscar::Presence OscarStatusManager::presenceOf( unsigned long oStatus, int oClass ) const
{
	using namespace Oscar;
	Presence::Type type = pscTypeForOscarStatus( oStatus );

	//Hack for aim away contacts
	if ( type == Presence::Online && (oClass & ClassCode::AWAY) == ClassCode::AWAY )
		type = Presence::Away;

	Presence::Flags flags = Presence::None;
	if ( (oClass & ClassCode::ICQ) == ClassCode::ICQ )
		flags |= Presence::ICQ;
	else
		flags |= Presence::AIM;

	if ( (oClass & ClassCode::WIRELESS) == ClassCode::WIRELESS )
		flags |= Presence::Wireless;

	if ( (oStatus & StatusCode::INVISIBLE) == StatusCode::INVISIBLE )
		flags |= Presence::Invisible;

	return Presence( type, flags );
}

unsigned long OscarStatusManager::basicOscarStatus( Oscar::Presence::Type type ) const
{
	const Oscar::PresenceType &data = pscTypeForType( type );
	return data.setFlag();
}

Oscar::Presence::Type OscarStatusManager::pscTypeForOscarStatus( unsigned long status ) const
{
	const Oscar::PresenceType &data = pscTypeForStatus( status & 0xff );
	return data.type();
}

Oscar::PresenceOverlay OscarStatusManager::pscOverlayForFlags( Oscar::Presence::Flags flags ) const
{
	Oscar::PresenceOverlay overlay;
	int size = d->presenceOverlayList.size();
	for ( int i = 0; i < size; i++ )
	{
		Oscar::PresenceOverlay data = d->presenceOverlayList.at(i);
		if ( data.flags() == flags )
			return data;
		else if ( data.flags() & flags )
			overlay += data;
	}

	return overlay;
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForType( Oscar::Presence::Type type ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = 0; n < size; ++n )
	{
		if ( d->presenceTypeList.at(n).type() == type )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "type " << (int)type << " not found! Returning Offline";
	return d->presenceTypeList.at(0);
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForStatus( unsigned long status ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = 0; n < size; ++n )
	{
		if ( (d->presenceTypeList.at(n).getFlag() & status) == d->presenceTypeList.at(n).getFlag() )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "status " << (int)status << " not found! Returning Offline. This should not happen.";
	return d->presenceTypeList.at(0);
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForOnlineStatusType( const Kopete::OnlineStatus::StatusType statusType ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = size - 1; n >= 0; --n )
	{
		if ( d->presenceTypeList.at(n).onlineStatusType() == statusType )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "online status " << (int)statusType << " not found! Returning Offline. This should not happen.";
	return d->presenceTypeList.at(0);
}

QString OscarStatusManager::kosDescription( const Oscar::Presence &presence ) const
{
	Oscar::PresenceOverlay overlay = pscOverlayForFlags( presence.flags() );
	const Oscar::PresenceType &type = pscTypeForType( presence.type() );

	QString desc = type.name();
	if ( !presence.description().isEmpty() )
		desc += QString(" - %1").arg( presence.description() );

	if ( !overlay.description().isEmpty() )
		desc += QString(" (%1)").arg( overlay.description() );

	return desc;
}

QString OscarStatusManager::descriptionFromKOS( const Kopete::OnlineStatus &status ) const
{
	Oscar::Presence presence( status.internalStatus() );
	Oscar::PresenceOverlay overlay = pscOverlayForFlags( presence.flags() );

	QString desc = status.description();
	if ( !overlay.description().isEmpty() )
	{
		QString overlayDesc = QString(" (%1)").arg( overlay.description() );
		if ( desc.endsWith( overlayDesc ) )
			desc.chop( overlayDesc.length() );
	}

	int idx = desc.indexOf( " - " );
	if ( idx > -1 )
		return desc.mid( idx + 3 );
	else
		return QString();
}
<commit_msg>Miranda sets away class when it is online so don't set away flag for ICQ.<commit_after>/*
    oscarstatusmanager.cpp  -  Oscar status manager

    Copyright (c) 2004      by Richard Smith          <kde@metafoo.co.uk>
    Copyright (c) 2006,2007 by Roman Jarosz           <kedgedev@centrum.cz>
    Kopete    (c) 2002-2007 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "oscarstatusmanager.h"

#include <QHash>

#include <kdebug.h>

#include "oscarprotocol.h"
#include "oscarpresencesdataclasses.h"

class OscarStatusManager::Private
{
public:
	OscarProtocol* protocol;

	typedef QHash<int, Kopete::OnlineStatus> StatusHash;
	StatusHash statusHash;

	QList<Oscar::PresenceType> presenceTypeList;
	QList<Oscar::PresenceOverlay> presenceOverlayList;

	Oscar::Presence::Flags mask;
};

OscarStatusManager::OscarStatusManager( OscarProtocol* protocol )
	: d( new Private() )
{
	d->protocol = protocol;
	d->mask = ~(Oscar::Presence::Flags)Oscar::Presence::None;
}

OscarStatusManager::~OscarStatusManager()
{
	delete d;
}

void OscarStatusManager::initialize( uint firstUsableWeight )
{
	for ( uint i = 0; i < Oscar::Presence::TypeCount; ++i )
	{
		const Oscar::PresenceType &data =  pscTypeForType( static_cast<Oscar::Presence::Type>(i) );
		const uint weight = i + firstUsableWeight;
		for ( int j = 0; j < data.overlayFlagsList().count(); ++j )
		{
			const uint internalStatus = data.overlayFlagsList().at(j) | data.type();

			Kopete::OnlineStatus status;
			if ( data.overlayFlagsList().at(j) != Oscar::Presence::None )
			{
				Oscar::PresenceOverlay overlay = pscOverlayForFlags( data.overlayFlagsList().at(j) );
				//don't add KOS to account's context menu
				status = Kopete::OnlineStatus( data.onlineStatusType(), weight,
				                               d->protocol, internalStatus,
				                               data.overlayIcons() + overlay.icons(),
				                               data.name() + QString(" (%1)").arg( overlay.description() ) );
			}
			else
			{
				//add KOS
				status = Kopete::OnlineStatus( data.onlineStatusType(), weight,
				                               d->protocol, internalStatus,
				                               data.overlayIcons(), data.name(),
				                               data.caption(), data.categories(), data.options() );
			}
			d->statusHash[internalStatus] = status;
		}
	}
}

void OscarStatusManager::setPresenceType( const QList<Oscar::PresenceType>& list )
{
	d->presenceTypeList = list;
}

void OscarStatusManager::setPresenceOverlay( const QList<Oscar::PresenceOverlay>& list )
{
	d->presenceOverlayList = list;
}

void OscarStatusManager::setPresenceFlagsMask( Oscar::Presence::Flags mask )
{
	d->mask = mask;
}

Kopete::OnlineStatus OscarStatusManager::onlineStatusOf( const Oscar::Presence &presence ) const
{
	Oscar::Presence pres( presence.internalStatus() & d->mask );
	pres.setDescription( presence.description() );

	if ( (pres.flags() & Oscar::Presence::XStatus) == Oscar::Presence::XStatus )
	{
		kDebug() << "Creating Kopete::OnlineStatus for XStatus, internal status: " << pres.internalStatus();
		// XStatus, we have to create new KOS
		Oscar::PresenceOverlay overlay = pscOverlayForFlags( pres.flags() );

		QString desc = kosDescription( pres );
		QString xtrazIcon = QString( "icq_xstatus%1" ).arg( pres.xtrazStatus() );
		return Kopete::OnlineStatus( Kopete::OnlineStatus::Online, 0, d->protocol, pres.internalStatus(),
		                             QStringList( xtrazIcon ) + overlay.icons(), desc );
	}
	else if ( (pres.flags() & Oscar::Presence::ExtStatus) == Oscar::Presence::ExtStatus )
	{
		kDebug() << "Creating Kopete::OnlineStatus for ExtStatus, internal status: " << pres.internalStatus();
		// ExtStatus, we have to create new KOS
		Oscar::PresenceOverlay overlay = pscOverlayForFlags( pres.flags() );
		const Oscar::PresenceType &type = pscTypeForType( pres.type() );

		QString desc = kosDescription( pres );
		return Kopete::OnlineStatus( type.onlineStatusType(), 0, d->protocol, pres.internalStatus(),
		                             type.overlayIcons() + overlay.icons(), desc );
	}
	else
	{
		if ( d->statusHash.contains( pres.internalStatus() ) )
		{
			return d->statusHash.value( pres.internalStatus() );
		}
		else if ( d->statusHash.contains( pres.type() ) )
		{
			kWarning() << "Kopete::OnlineStatus doesn't exists for internal status " << pres.internalStatus()
			           << " Using basic status for type " << pres.type() << endl;
			return d->statusHash.value( pres.type() );
		}
		else
		{
			kWarning() << "Kopete::OnlineStatus doesn't exists for internal status " << pres.internalStatus();
			return unknownStatus();
		}
	}
}

Oscar::Presence OscarStatusManager::presenceOf( const Kopete::OnlineStatus &status ) const
{
	if ( status.protocol() == d->protocol )
	{
		Oscar::Presence presence( status.internalStatus() );
		if ( (presence.flags() & Oscar::Presence::XStatus) || (presence.flags() & Oscar::Presence::ExtStatus) )
		{
			// ExtStatus/XStatus, we have to filter out description
			presence.setDescription( descriptionFromKOS( status ) );
		}
		return presence;
	}
	else
	{
		//status is a libkopete builtin status object
		//don't even think about converting it to Oscar::Presence using presenceOf!
		return Oscar::Presence( pscTypeForOnlineStatusType( status.status() ).type(),
		                        Oscar::Presence::None );
	}
}

unsigned long OscarStatusManager::oscarStatusOf( const Oscar::Presence &presence ) const
{
	unsigned long basicStatus = basicOscarStatus( presence.type() );
	if ( (presence.internalStatus() & Oscar::Presence::Invisible) == Oscar::Presence::Invisible )
		basicStatus |= Oscar::StatusCode::INVISIBLE;
	return basicStatus;
}

Oscar::Presence OscarStatusManager::presenceOf( unsigned long oStatus, int oClass ) const
{
	using namespace Oscar;
	Presence::Type type = pscTypeForOscarStatus( oStatus );

	//Hack for aim away contacts
	if ( type == Presence::Online && (oClass & ClassCode::AWAY) == ClassCode::AWAY
	     && (oClass & ClassCode::ICQ) == 0 )
		type = Presence::Away;

	Presence::Flags flags = Presence::None;
	if ( (oClass & ClassCode::ICQ) == ClassCode::ICQ )
		flags |= Presence::ICQ;
	else
		flags |= Presence::AIM;

	if ( (oClass & ClassCode::WIRELESS) == ClassCode::WIRELESS )
		flags |= Presence::Wireless;

	if ( (oStatus & StatusCode::INVISIBLE) == StatusCode::INVISIBLE )
		flags |= Presence::Invisible;

	return Presence( type, flags );
}

unsigned long OscarStatusManager::basicOscarStatus( Oscar::Presence::Type type ) const
{
	const Oscar::PresenceType &data = pscTypeForType( type );
	return data.setFlag();
}

Oscar::Presence::Type OscarStatusManager::pscTypeForOscarStatus( unsigned long status ) const
{
	const Oscar::PresenceType &data = pscTypeForStatus( status & 0xff );
	return data.type();
}

Oscar::PresenceOverlay OscarStatusManager::pscOverlayForFlags( Oscar::Presence::Flags flags ) const
{
	Oscar::PresenceOverlay overlay;
	int size = d->presenceOverlayList.size();
	for ( int i = 0; i < size; i++ )
	{
		Oscar::PresenceOverlay data = d->presenceOverlayList.at(i);
		if ( data.flags() == flags )
			return data;
		else if ( data.flags() & flags )
			overlay += data;
	}

	return overlay;
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForType( Oscar::Presence::Type type ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = 0; n < size; ++n )
	{
		if ( d->presenceTypeList.at(n).type() == type )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "type " << (int)type << " not found! Returning Offline";
	return d->presenceTypeList.at(0);
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForStatus( unsigned long status ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = 0; n < size; ++n )
	{
		if ( (d->presenceTypeList.at(n).getFlag() & status) == d->presenceTypeList.at(n).getFlag() )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "status " << (int)status << " not found! Returning Offline. This should not happen.";
	return d->presenceTypeList.at(0);
}

const Oscar::PresenceType &OscarStatusManager::pscTypeForOnlineStatusType( const Kopete::OnlineStatus::StatusType statusType ) const
{
	int size = d->presenceTypeList.size();
	for ( int n = size - 1; n >= 0; --n )
	{
		if ( d->presenceTypeList.at(n).onlineStatusType() == statusType )
			return d->presenceTypeList.at(n);
	}

	kWarning(14153) << "online status " << (int)statusType << " not found! Returning Offline. This should not happen.";
	return d->presenceTypeList.at(0);
}

QString OscarStatusManager::kosDescription( const Oscar::Presence &presence ) const
{
	Oscar::PresenceOverlay overlay = pscOverlayForFlags( presence.flags() );
	const Oscar::PresenceType &type = pscTypeForType( presence.type() );

	QString desc = type.name();
	if ( !presence.description().isEmpty() )
		desc += QString(" - %1").arg( presence.description() );

	if ( !overlay.description().isEmpty() )
		desc += QString(" (%1)").arg( overlay.description() );

	return desc;
}

QString OscarStatusManager::descriptionFromKOS( const Kopete::OnlineStatus &status ) const
{
	Oscar::Presence presence( status.internalStatus() );
	Oscar::PresenceOverlay overlay = pscOverlayForFlags( presence.flags() );

	QString desc = status.description();
	if ( !overlay.description().isEmpty() )
	{
		QString overlayDesc = QString(" (%1)").arg( overlay.description() );
		if ( desc.endsWith( overlayDesc ) )
			desc.chop( overlayDesc.length() );
	}

	int idx = desc.indexOf( " - " );
	if ( idx > -1 )
		return desc.mid( idx + 3 );
	else
		return QString();
}
<|endoftext|>


<commit_before>/*
	This file is part of the CVD Library.

	Copyright (C) 2005 The Authors

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
inline ImageRef::ImageRef()
{
	x=y=0;
}

inline ImageRef::ImageRef(int xp, int yp)
:x(xp),y(yp)
{}

inline ImageRef::ImageRef(std::istream& is)
{
	is.read((char*)&x,sizeof(int));
	is.read((char*)&y,sizeof(int));
}

	//////////////////////////////////////////////////////////////////////////
	// the following cryptic pieces of rubbish are because inline functions //
	// must have their one and only return function as the last call        //
	// so this code makes use of the fact that expressions to the right     //
	// of || are only evaluated when the left hand side is false            //
	//////////////////////////////////////////////////////////////////////////

inline bool ImageRef::next(const ImageRef& max)	// move on to the next value
{
	return(++x != max.x || (x=0, ++y != max.y) || (y=0, false));
}

inline bool ImageRef::next(const ImageRef& min, const ImageRef& max)
{
	return (++x != max.x || (x=min.x, ++y != max.y) || (y=min.y, false));
}

inline bool ImageRef::prev(const ImageRef& max)	// move back to the previous value
{
	return(--x != -1 || (x=max.x-1, --y != -1) || (y=max.y-1, false));
}

inline bool ImageRef::prev(const ImageRef& min, const ImageRef& max)
{
	return (--x != min.x-1 || (x=max.x-1, --y != min.y-1) || (y=max.y-1, false));
}

inline void ImageRef::home()
{
	x=y=0;
}

inline void ImageRef::end(const ImageRef& size)
{
	x=size.x-1;
	y=size.y-1;
}

inline ImageRef& ImageRef::operator=(const ImageRef& ref)
{
	x=ref.x;
	y=ref.y;
	return *this;
}

inline bool ImageRef::operator ==(const ImageRef& ref) const
{
	return (x==ref.x && y==ref.y);
}

inline bool ImageRef::operator !=(const ImageRef& ref) const
{
	return (x!=ref.x || y!=ref.y);
}

inline ImageRef ImageRef::operator-() const
{
  ImageRef v(-x, -y);
  return v;
}

inline ImageRef& ImageRef::operator*=(const double scale)
{
  x=(int)(x*scale);
  y=(int)(y*scale);
  return *this;
}

inline ImageRef& ImageRef::operator/=(const double scale)
{
	x=(int)(x/scale);
	y=(int)(y/scale);
	return *this;
}

inline ImageRef& ImageRef::operator+=(const ImageRef rhs)
{
	x+=rhs.x;
	y+=rhs.y;
	return *this;
}

inline ImageRef& ImageRef::operator-=(const ImageRef rhs)
{
	x-=rhs.x;
	y-=rhs.y;
	return *this;
}

inline ImageRef ImageRef::operator*(const double scale) const
{
	ImageRef v((int)(x*scale),(int)(y*scale));
	return v;
}

inline ImageRef ImageRef::operator/(const double scale) const
{
	ImageRef v((int)(x/scale),(int)(y/scale));
	return v;
}

inline ImageRef ImageRef::operator+(const ImageRef rhs) const
{
	ImageRef v(x+rhs.x, y+rhs.y);
	return v;
}

inline ImageRef ImageRef::operator-(const ImageRef rhs) const
{
	ImageRef v(x-rhs.x, y-rhs.y);
	return v;
}

inline ImageRef& ImageRef::operator<<=(int i)
{
	x = x << i;
	y=y << i;
	return *this;
}

inline ImageRef& ImageRef::operator>>=(int i)
{
	x = x >> i;
	y=y >> i;
	return *this;
}

inline ImageRef ImageRef::shiftl(int i) const
{
	ImageRef result;
	result.x = x << i;
	result.y=y << i;
	return result;
}

inline ImageRef ImageRef::shiftr(int i) const
{
	ImageRef result;
	result.x = x >> i;
	result.y=y >> i;
	return result;
}

inline ImageRef ImageRef::operator<<(int i) const
{
	return shiftl(i);
}

inline ImageRef ImageRef::operator>>(int i) const
{
	return shiftr(i);
}

inline ImageRef operator*(const int scale, const ImageRef&  ref)
{
	return ImageRef(ref.x*scale, ref.y*scale);
}

inline bool ImageRef::operator<(const ImageRef & other) const
{
  return y < other.y || ( y == other.y && x < other.x);
}

inline bool ImageRef::operator>(const ImageRef & other) const
{
  return y > other.y || ( y == other.y && x > other.x);
}

inline int& ImageRef::operator[](int i)
{
  if(i==0)
    return x;
  if(i==1)
    return y;
  throw Exceptions::BadSubscript();
}

inline int ImageRef::operator[](int i) const
{
  if(i==0)
    return x;
  if(i==1)
    return y;
  throw Exceptions::BadSubscript();
}

inline unsigned int ImageRef::mag_squared() const
{
  typedef unsigned int uint;
  return uint(x*x) + uint(y*y);
}

inline int ImageRef::area() const
{
  return x * y;
}

inline ImageRef ImageRef::dot_times(const ImageRef &ref) const
{
  return ImageRef(x * ref.x, y * ref.y);
}
<commit_msg>make ImageRef::next, prev work for min >= max<commit_after>/*
	This file is part of the CVD Library.

	Copyright (C) 2005 The Authors

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
inline ImageRef::ImageRef()
{
	x=y=0;
}

inline ImageRef::ImageRef(int xp, int yp)
:x(xp),y(yp)
{}

inline ImageRef::ImageRef(std::istream& is)
{
	is.read((char*)&x,sizeof(int));
	is.read((char*)&y,sizeof(int));
}

	//////////////////////////////////////////////////////////////////////////
	// the following cryptic pieces of rubbish are because inline functions //
	// must have their one and only return function as the last call        //
	// so this code makes use of the fact that expressions to the right     //
	// of || are only evaluated when the left hand side is false            //
	//////////////////////////////////////////////////////////////////////////

inline bool ImageRef::next(const ImageRef& max)	// move on to the next value
{
	return(++x < max.x || (x=0, ++y < max.y) || (y=0, false));
}

inline bool ImageRef::next(const ImageRef& min, const ImageRef& max)
{
	return (++x < max.x || (x=min.x, ++y < max.y) || (y=min.y, false));
}

inline bool ImageRef::prev(const ImageRef& max)	// move back to the previous value
{
	return(--x > -1 || (x=max.x-1, --y > -1) || (y=max.y-1, false));
}

inline bool ImageRef::prev(const ImageRef& min, const ImageRef& max)
{
	return (--x > min.x-1 || (x=max.x-1, --y > min.y-1) || (y=max.y-1, false));
}

inline void ImageRef::home()
{
	x=y=0;
}

inline void ImageRef::end(const ImageRef& size)
{
	x=size.x-1;
	y=size.y-1;
}

inline ImageRef& ImageRef::operator=(const ImageRef& ref)
{
	x=ref.x;
	y=ref.y;
	return *this;
}

inline bool ImageRef::operator ==(const ImageRef& ref) const
{
	return (x==ref.x && y==ref.y);
}

inline bool ImageRef::operator !=(const ImageRef& ref) const
{
	return (x!=ref.x || y!=ref.y);
}

inline ImageRef ImageRef::operator-() const
{
  ImageRef v(-x, -y);
  return v;
}

inline ImageRef& ImageRef::operator*=(const double scale)
{
  x=(int)(x*scale);
  y=(int)(y*scale);
  return *this;
}

inline ImageRef& ImageRef::operator/=(const double scale)
{
	x=(int)(x/scale);
	y=(int)(y/scale);
	return *this;
}

inline ImageRef& ImageRef::operator+=(const ImageRef rhs)
{
	x+=rhs.x;
	y+=rhs.y;
	return *this;
}

inline ImageRef& ImageRef::operator-=(const ImageRef rhs)
{
	x-=rhs.x;
	y-=rhs.y;
	return *this;
}

inline ImageRef ImageRef::operator*(const double scale) const
{
	ImageRef v((int)(x*scale),(int)(y*scale));
	return v;
}

inline ImageRef ImageRef::operator/(const double scale) const
{
	ImageRef v((int)(x/scale),(int)(y/scale));
	return v;
}

inline ImageRef ImageRef::operator+(const ImageRef rhs) const
{
	ImageRef v(x+rhs.x, y+rhs.y);
	return v;
}

inline ImageRef ImageRef::operator-(const ImageRef rhs) const
{
	ImageRef v(x-rhs.x, y-rhs.y);
	return v;
}

inline ImageRef& ImageRef::operator<<=(int i)
{
	x = x << i;
	y=y << i;
	return *this;
}

inline ImageRef& ImageRef::operator>>=(int i)
{
	x = x >> i;
	y=y >> i;
	return *this;
}

inline ImageRef ImageRef::shiftl(int i) const
{
	ImageRef result;
	result.x = x << i;
	result.y=y << i;
	return result;
}

inline ImageRef ImageRef::shiftr(int i) const
{
	ImageRef result;
	result.x = x >> i;
	result.y=y >> i;
	return result;
}

inline ImageRef ImageRef::operator<<(int i) const
{
	return shiftl(i);
}

inline ImageRef ImageRef::operator>>(int i) const
{
	return shiftr(i);
}

inline ImageRef operator*(const int scale, const ImageRef&  ref)
{
	return ImageRef(ref.x*scale, ref.y*scale);
}

inline bool ImageRef::operator<(const ImageRef & other) const
{
  return y < other.y || ( y == other.y && x < other.x);
}

inline bool ImageRef::operator>(const ImageRef & other) const
{
  return y > other.y || ( y == other.y && x > other.x);
}

inline int& ImageRef::operator[](int i)
{
  if(i==0)
    return x;
  if(i==1)
    return y;
  throw Exceptions::BadSubscript();
}

inline int ImageRef::operator[](int i) const
{
  if(i==0)
    return x;
  if(i==1)
    return y;
  throw Exceptions::BadSubscript();
}

inline unsigned int ImageRef::mag_squared() const
{
  typedef unsigned int uint;
  return uint(x*x) + uint(y*y);
}

inline int ImageRef::area() const
{
  return x * y;
}

inline ImageRef ImageRef::dot_times(const ImageRef &ref) const
{
  return ImageRef(x * ref.x, y * ref.y);
}
<|endoftext|>