<commit_before>// __BEGIN_LICENSE__
// 
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
// 
// Copyright 2006 <NAME>. All rights reserved.
// 
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
// 
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
// 
// __END_LICENSE__

/// \file ImageComposte.h
/// 
/// A view class that represents a composite mosaic of images.
/// 
#ifndef __VW_MOSAIC_IMAGECOMPOSITE_H__
#define __VW_MOSAIC_IMAGECOMPOSITE_H__

#include <iostream>
#include <vector>
#include <list>

#include <vw/Core/Cache.h>
#include <vw/Core/ProgressCallback.h>
#include <vw/Math/BBox.h>
#include <vw/Image/ImageView.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/Filter.h>
#include <vw/Image/EdgeExtension.h>
#include <vw/Image/Manipulation.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/Transform.h>
#include <vw/Image/Algorithms.h>
#include <vw/FileIO/DiskImageResource.h>

namespace vw {
namespace mosaic {

  // *******************************************************************
  // PositionedImage
  // *******************************************************************

  template <class PixelT>
  class PositionedImage : public ImageViewBase<PositionedImage<PixelT> > {
  public:
    int cols_, rows_;
    ImageView<PixelT> image;
    BBox<int,2> bbox;

    typedef PixelT pixel_type;
    typedef PixelT result_type;

    template <class ImageT>
    PositionedImage( int cols, int rows, ImageT const& image, BBox<int,2> const& bbox ) : cols_(cols), rows_(rows), image(image), bbox(bbox) {}

    PositionedImage reduce() const {
      const int border = 1;
      int left = std::min( border + (bbox.min().x()+border)%2, bbox.min().x() );
      int top = std::min( border + (bbox.min().y()+border)%2, bbox.min().y() );
      int right = std::min( border + (bbox.width()+left+border)%2, cols_-bbox.min().x()-bbox.width() );
      int bottom = std::min( border + (bbox.height()+top+border)%2, rows_-bbox.min().y()-bbox.height() );
      std::vector<float> kernel(3); kernel[0]=0.25; kernel[1]=0.5; kernel[2]=0.25;
      // I don't quite yet understand why (if?) this is the correct bounding box,
      // but bad things happen without the final "+1"s:
      BBox<int,2> new_bbox( Vector<int,2>( (bbox.min().x()-left)/2, (bbox.min().y()-top)/2 ),
                            Vector<int,2>( (bbox.min().x()-left)/2 + (bbox.width()+left+right+1)/2+1,
                                                (bbox.min().y()-top)/2 + (bbox.height()+top+bottom+1)/2+1 ) );
      // We use vw::rasterize() here rather than ordinary assignment because it is 
      // faster for this particular combination of filtering and subsampling.
      ImageView<PixelT> new_image( new_bbox.width(), new_bbox.height() );
      vw::rasterize( edge_extend( subsample( separable_convolution_filter( edge_extend( image, -left, -top, image.cols()+left+right, image.rows()+top+bottom, ZeroEdgeExtension() ),
                                                                           kernel, kernel, ZeroEdgeExtension() ), 2 ), 0, 0, new_bbox.width(), new_bbox.height(), vw::ConstantEdgeExtension() ),
                     new_image );
      return PositionedImage( (cols_+1)/2, (rows_+1)/2, new_image, new_bbox );
    }
    
    void unpremultiply() {
      image /= select_alpha_channel( image );
    }

    void addto( ImageView<PixelT> const& dest ) const {
      crop( dest, bbox ) += image;
    }

    // Performs additive composition when overlay==false (the default).
    // When overlay==true, it overlays the image on top of the destination,
    // respecting any alpha channel.
    void addto( ImageView<PixelT> const& dest, int ox, int oy, bool overlay = false ) {
      BBox<int,2> sum_bbox = bbox;
      sum_bbox.crop( BBox<int,2>( Vector<int,2>(ox,oy), Vector<int,2>(ox+dest.cols(),oy+dest.rows()) ) );
      if( sum_bbox.empty() ) return;
      if( overlay ) {
        if( PixelHasAlpha<PixelT>::value ) {
          // FIXME This doesn't work for integer pixel types!
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) *= 1.0 - select_alpha_channel( crop( image, sum_bbox-bbox.min() ) );
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) += crop( image, sum_bbox-bbox.min() );
        }
        else {
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) = crop( image, sum_bbox-bbox.min() );
        }
      }
      else {
        crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) += crop( image, sum_bbox-bbox.min() );
      }
    }

    void subtract_expanded( PositionedImage const& other ) {
      vw::rasterize( image - edge_extend( resample( other.image, 2 ), bbox-2*other.bbox.min(), ZeroEdgeExtension() ), image );<commit_msg>Fixed a bug in draft-compositing integer images.<commit_after>// __BEGIN_LICENSE__
// 
// Copyright (C) 2006 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA).  All Rights Reserved.
// 
// Copyright 2006 <NAME> University. All rights reserved.
// 
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3.  The NOSA has been approved by the Open Source
// Initiative.  See the file COPYING at the top of the distribution
// directory tree for the complete NOSA document.
// 
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
// 
// __END_LICENSE__

/// \file ImageComposte.h
/// 
/// A view class that represents a composite mosaic of images.
/// 
#ifndef __VW_MOSAIC_IMAGECOMPOSITE_H__
#define __VW_MOSAIC_IMAGECOMPOSITE_H__

#include <iostream>
#include <vector>
#include <list>

#include <vw/Core/Cache.h>
#include <vw/Core/ProgressCallback.h>
#include <vw/Math/BBox.h>
#include <vw/Image/ImageView.h>
#include <vw/Image/ImageViewRef.h>
#include <vw/Image/Filter.h>
#include <vw/Image/EdgeExtension.h>
#include <vw/Image/Manipulation.h>
#include <vw/Image/ImageMath.h>
#include <vw/Image/Transform.h>
#include <vw/Image/Algorithms.h>
#include <vw/FileIO/DiskImageResource.h>

namespace vw {
namespace mosaic {

  // *******************************************************************
  // PositionedImage
  // *******************************************************************

  template <class PixelT>
  class PositionedImage : public ImageViewBase<PositionedImage<PixelT> > {
  public:
    int cols_, rows_;
    ImageView<PixelT> image;
    BBox<int,2> bbox;

    typedef PixelT pixel_type;
    typedef PixelT result_type;

    template <class ImageT>
    PositionedImage( int cols, int rows, ImageT const& image, BBox<int,2> const& bbox ) : cols_(cols), rows_(rows), image(image), bbox(bbox) {}

    PositionedImage reduce() const {
      const int border = 1;
      int left = std::min( border + (bbox.min().x()+border)%2, bbox.min().x() );
      int top = std::min( border + (bbox.min().y()+border)%2, bbox.min().y() );
      int right = std::min( border + (bbox.width()+left+border)%2, cols_-bbox.min().x()-bbox.width() );
      int bottom = std::min( border + (bbox.height()+top+border)%2, rows_-bbox.min().y()-bbox.height() );
      std::vector<float> kernel(3); kernel[0]=0.25; kernel[1]=0.5; kernel[2]=0.25;
      // I don't quite yet understand why (if?) this is the correct bounding box,
      // but bad things happen without the final "+1"s:
      BBox<int,2> new_bbox( Vector<int,2>( (bbox.min().x()-left)/2, (bbox.min().y()-top)/2 ),
                            Vector<int,2>( (bbox.min().x()-left)/2 + (bbox.width()+left+right+1)/2+1,
                                                (bbox.min().y()-top)/2 + (bbox.height()+top+bottom+1)/2+1 ) );
      // We use vw::rasterize() here rather than ordinary assignment because it is 
      // faster for this particular combination of filtering and subsampling.
      ImageView<PixelT> new_image( new_bbox.width(), new_bbox.height() );
      vw::rasterize( edge_extend( subsample( separable_convolution_filter( edge_extend( image, -left, -top, image.cols()+left+right, image.rows()+top+bottom, ZeroEdgeExtension() ),
                                                                           kernel, kernel, ZeroEdgeExtension() ), 2 ), 0, 0, new_bbox.width(), new_bbox.height(), vw::ConstantEdgeExtension() ),
                     new_image );
      return PositionedImage( (cols_+1)/2, (rows_+1)/2, new_image, new_bbox );
    }
    
    void unpremultiply() {
      image /= select_alpha_channel( image );
    }

    void addto( ImageView<PixelT> const& dest ) const {
      crop( dest, bbox ) += image;
    }

    // Performs additive composition when overlay==false (the default).
    // When overlay==true, it overlays the image on top of the destination,
    // respecting any alpha channel.
    void addto( ImageView<PixelT> const& dest, int ox, int oy, bool overlay = false ) {
      BBox<int,2> sum_bbox = bbox;
      sum_bbox.crop( BBox<int,2>( Vector<int,2>(ox,oy), Vector<int,2>(ox+dest.cols(),oy+dest.rows()) ) );
      if( sum_bbox.empty() ) return;
      if( overlay ) {
        if( PixelHasAlpha<PixelT>::value ) {
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) *= 1.0 - select_alpha_channel( crop( image, sum_bbox-bbox.min() ) ) / (double)ChannelRange<PixelT>::max();
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) += crop( image, sum_bbox-bbox.min() );
        }
        else {
          crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) = crop( image, sum_bbox-bbox.min() );
        }
      }
      else {
        crop( dest, sum_bbox-Vector<int,2>(ox,oy) ) += crop( image, sum_bbox-bbox.min() );
      }
    }

    void subtract_expanded( PositionedImage const& other ) {
      vw::rasterize( image - edge_extend( resample( other.image, 2 ), bbox-2*other.bbox.min(), ZeroEdgeExtension() ), image );
{'fraction_non_alphanumeric': 0.16602281089036056, 'fraction_numerical': 0.011405445180279618, 'mean_word_length': 3.198069498069498, 'pattern_counts': {'":': 0, '<': 82, '<?xml version=': 0, '>': 82, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3197839', 'n_tokens_mistral': 3619, 'n_tokens_neox': 3494, 'n_words': 924}