<commit_before>// Copyright 2019 The TCMalloc Authors
//
// 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
//
//     https://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 "tcmalloc/transfer_cache.h"

#include <string.h>

#include <algorithm>
#include <atomic>

#include "absl/base/attributes.h"
#include "tcmalloc/common.h"
#include "tcmalloc/experiment.h"
#include "tcmalloc/guarded_page_allocator.h"
#include "tcmalloc/internal/linked_list.h"
#include "tcmalloc/internal/logging.h"
#include "tcmalloc/static_vars.h"
#include "tcmalloc/tracking.h"

namespace tcmalloc {
#ifndef TCMALLOC_SMALL_BUT_SLOW
class EvictionManager {
 public:
  constexpr EvictionManager() : next_(1) {}

  int DetermineSizeClassToEvict() {
    int t = next_.load(std::memory_order_relaxed);
    if (t >= kNumClasses) t = 1;
    next_.store(t + 1, std::memory_order_relaxed);

    // Ask nicely first.
    int N = Static::sizemap()->num_objects_to_move(t);
    auto info = Static::transfer_cache()[t].GetSlotInfo();
    if (info.capacity - info.used >= N) {
      return t;
    }

    // But insist on the second try.
    t = next_.load(std::memory_order_relaxed);
    if (t >= kNumClasses) t = 1;
    next_.store(t + 1, std::memory_order_relaxed);
    return t;
  }

 private:
  std::atomic<int32_t> next_;
};

ABSL_CONST_INIT EvictionManager gEvictionManager;

void TransferCache::Init(size_t cl) {
  absl::base_internal::SpinLockHolder h(&lock_);
  freelist_.Init(cl);

  // We need at least 2 slots to store list head and tail.
  ASSERT(kMinObjectsToMove >= 2);

  // Cache this value, for performance.
  arbitrary_transfer_ =
      IsExperimentActive(Experiment::TCMALLOC_ARBITRARY_TRANSFER_CACHE);

  slots_ = nullptr;
  max_capacity_ = 0;
  SizeInfo info = {0, 0};

  if (cl > 0) {
    // Limit the maximum size of the cache based on the size class.  If this
    // is not done, large size class objects will consume a lot of memory if
    // they just sit in the transfer cache.
    size_t bytes = Static::sizemap()->class_to_size(cl);
    size_t objs_to_move = Static::sizemap()->num_objects_to_move(cl);
    ASSERT(objs_to_move > 0 && bytes > 0);

    // Starting point for the maximum number of entries in the transfer cache.
    // This actual maximum for a given size class may be lower than this
    // maximum value.
    max_capacity_ = 64 * objs_to_move;
    // A transfer cache freelist can have anywhere from 0 to
    // max_capacity_ slots to put link list chains into.
    info.capacity = 16 * objs_to_move;

    // Limit each size class cache to at most 1MB of objects or one entry,
    // whichever is greater. Total transfer cache memory used across all
    // size classes then can't be greater than approximately
    // 1MB * kMaxNumTransferEntries.
    max_capacity_ = std::clamp<size_t>(
        objs_to_move, max_capacity_,
        (1024 * 1024) / (bytes * objs_to_move) * objs_to_move);
    info.capacity = std::min(info.capacity, max_capacity_);
    slots_ = reinterpret_cast<void **>(
        Static::arena()->Alloc(max_capacity_ * sizeof(void *)));
  }
  SetSlotInfo(info);
}

bool TransferCache::MakeCacheSpace(int N) {
  auto info = slot_info_.load(std::memory_order_relaxed);
  // Is there room in the cache?
  if (info.used + N <= info.capacity) return true;
  // Check if we can expand this cache?
  if (info.capacity + N > max_capacity_) return false;

  int to_evict = gEvictionManager.DetermineSizeClassToEvict();
  if (to_evict == freelist_.size_class()) return false;

  // Release the held lock before the other instance tries to grab its lock.
  lock_.Unlock();
  bool made_space = Static::transfer_cache()[to_evict].ShrinkCache();
  lock_.Lock();

  if (!made_space) return false;

  // Succeeded in evicting, we're going to make our cache larger.  However, we
  // may have dropped and re-acquired the lock, so the cache_size may have
  // changed.  Therefore, check and verify that it is still OK to increase the
  // cache_size.
  info = slot_info_.load(std::memory_order_relaxed);
  if (info.capacity + N > max_capacity_) return false;
  info.capacity += N;
  SetSlotInfo(info);
  return true;
}

bool TransferCache::ShrinkCache() {
  auto info = slot_info_.load(std::memory_order_relaxed);

  // Start with a quick check without taking a lock.
  if (info.capacity == 0) return false;

  int N = Static::sizemap()->num_objects_to_move(freelist_.size_class());

  void *to_free[kMaxObjectsToMove];
  int num_to_free;
  {
    absl::base_internal::SpinLockHolder h(&lock_);

    // Fetch while holding the lock in case they changed.
    info = slot_info_.load(std::memory_order_relaxed);

    if (info.capacity == 0) return false;
    if (!arbitrary_transfer_ && info.capacity < N) return false;

    N = std::min(N, info.capacity);
    int unused = info.capacity - info.used;
    if (N <= unused) {
      info.capacity -= N;
      SetSlotInfo(info);
      return true;
    }

    num_to_free = N - unused;
    info.capacity -= N;
    info.used -= num_to_free;
    SetSlotInfo(info);
    // Our internal slot array may get overwritten as soon as we drop the lock,
    // so copy the items to free to an on stack buffer.
    memcpy(to_free, GetSlot(info.used), sizeof(void *) * num_to_free);
  }

  // Access the freelist without holding the lock.
  freelist_.InsertRange(to_free, num_to_free);
  return true;
}

void TransferCache::InsertRange(absl::Span<void *> batch, int N) {
  const int B = Static::sizemap()->num_objects_to_move(freelist_.size_class());
  ASSERT(0 < N && N <= B);
  auto info = slot_info_.load(std::memory_order_relaxed);
  if (N == B && info.used + N <= max_capacity_) {
    absl::base_internal::SpinLockHolder h(&lock_);
    if (MakeCacheSpace(N)) {
      // MakeCacheSpace can drop the lock, so refetch
      info = slot_info_.load(std::memory_order_relaxed);
      info.used += N;
      SetSlotInfo(info);

      void **entry = GetSlot(info.used - N);
      memcpy(entry, batch.data(), sizeof(void *) * N);
      tracking::Report(kTCInsertHit, freelist_.size_class(), 1);
      return;
    }
  } else if (arbitrary_transfer_) {
    absl::base_internal::SpinLockHolder h(&lock_);
    MakeCacheSpace(N);
    // MakeCacheSpace can drop the lock, so refetch
    info = slot_info_.load(std::memory_order_relaxed);
    int unused = info.capacity - info.used;
    if (N < unused) {
      info.used += N;
      SetSlotInfo(info);
      void **entry = GetSlot(info.used - N);
      memcpy(entry, batch.data(), sizeof(void *) * N);
      tracking::Report(kTCInsertHit, freelist_.size_class(), 1);
      return;
    }
    // We could not fit the entire batch into the transfer cache
    // so send the batch to the freelist and also take some elements from
    // the transfer cache so that we amortise the cost of accessing spans
    // in the freelist. Only do this if caller has sufficient space in
    // batch.
    // First of all fill up the rest of the batch with elements from the
    // transfer cache.
    int extra = B - N;
    if (N > 1 && extra > 0 && info.used > 0 && batch.size() >= B) {
      // Take at most all the objects present
      extra = std::min(extra, info.used);
      ASSERT(extra + N <= kMaxObjectsToMove);
      info.used -= extra;
      SetSlotInfo(info);

      void **entry = GetSlot(info.used);
      memcpy(batch.data() + N, entry, sizeof(void *) * extra);
      N += extra;
#ifndef NDEBUG
      int rest = batch.size() - N - 1;
      if (rest > 0) {
        memset(batch.data() + N, 0x3f, rest * sizeof(void *));
      }
#endif
    }
  }
  tracking::Report(kTCInsertMiss, freelist_.size_class(), 1);
  freelist_.InsertRange(batch.data(), N);
}

int TransferCache::RemoveRange(void **batch, int N) {
  ASSERT(N > 0);
  const int B = Static::sizemap()->num_objects_to_move(freelist_.size_class());
  int fetch = 0;
  auto info = slot_info_.load(std::memory_order_relaxed);
  if (N == B && info.used >= N) {
    absl::base_internal::SpinLockHolder h(&lock_);
    // Refetch with the lock
    info = slot_info_.load(std::memory_order_relaxed);
    if (info.used >= N) {
      info.used -= N;
      SetSlotInfo(info);
      void **entry = GetSlot(info.used);
      memcpy(batch, entry, sizeof(void *) * N);
      tracking::Report(kTCRemoveHit, freelist_.size_class(), 1);
      return N;
    }
  } else if (arbitrary_transfer_ && info.used >= 0) {
    absl::base_internal::SpinLockHolder h(&lock_);
    // Refetch with the lock
    info = slot_info_.load(std::memory_order_relaxed);

    fetch = std::min(N, info.used);
    info.used -= fetch;
    SetSlotInfo(info);
    void **entry = GetSlot(info.used);
    memcpy(batch, entry, sizeof(void *) * fetch);
    tracking::Report(kTCRemoveHit, freelist_.size_class(), 1);
    if (fetch == N) return N;
  }
  tracking::Report(kTCRemoveMiss, freelist_.size_class(), 1);
  return freelist_.RemoveRange(batch + fetch, N - fetch) + fetch;
}

size_t TransferCache::tc_length() {
  return static_cast<size_t>(slot_info_.load(std::memory_order_relaxed).used);
}

#endif
}  // namespace tcmalloc
<commit_msg>Revert use std::clamp instead of nested min/max calls.<commit_after>// Copyright 2019 The TCMalloc Authors
//
// 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
//
//     https://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 "tcmalloc/transfer_cache.h"

#include <string.h>

#include <algorithm>
#include <atomic>

#include "absl/base/attributes.h"
#include "tcmalloc/common.h"
#include "tcmalloc/experiment.h"
#include "tcmalloc/guarded_page_allocator.h"
#include "tcmalloc/internal/linked_list.h"
#include "tcmalloc/internal/logging.h"
#include "tcmalloc/static_vars.h"
#include "tcmalloc/tracking.h"

namespace tcmalloc {
#ifndef TCMALLOC_SMALL_BUT_SLOW
class EvictionManager {
 public:
  constexpr EvictionManager() : next_(1) {}

  int DetermineSizeClassToEvict() {
    int t = next_.load(std::memory_order_relaxed);
    if (t >= kNumClasses) t = 1;
    next_.store(t + 1, std::memory_order_relaxed);

    // Ask nicely first.
    int N = Static::sizemap()->num_objects_to_move(t);
    auto info = Static::transfer_cache()[t].GetSlotInfo();
    if (info.capacity - info.used >= N) {
      return t;
    }

    // But insist on the second try.
    t = next_.load(std::memory_order_relaxed);
    if (t >= kNumClasses) t = 1;
    next_.store(t + 1, std::memory_order_relaxed);
    return t;
  }

 private:
  std::atomic<int32_t> next_;
};

ABSL_CONST_INIT EvictionManager gEvictionManager;

void TransferCache::Init(size_t cl) {
  absl::base_internal::SpinLockHolder h(&lock_);
  freelist_.Init(cl);

  // We need at least 2 slots to store list head and tail.
  ASSERT(kMinObjectsToMove >= 2);

  // Cache this value, for performance.
  arbitrary_transfer_ =
      IsExperimentActive(Experiment::TCMALLOC_ARBITRARY_TRANSFER_CACHE);

  slots_ = nullptr;
  max_capacity_ = 0;
  SizeInfo info = {0, 0};

  if (cl > 0) {
    // Limit the maximum size of the cache based on the size class.  If this
    // is not done, large size class objects will consume a lot of memory if
    // they just sit in the transfer cache.
    size_t bytes = Static::sizemap()->class_to_size(cl);
    size_t objs_to_move = Static::sizemap()->num_objects_to_move(cl);
    ASSERT(objs_to_move > 0 && bytes > 0);

    // Starting point for the maximum number of entries in the transfer cache.
    // This actual maximum for a given size class may be lower than this
    // maximum value.
    max_capacity_ = 64 * objs_to_move;
    // A transfer cache freelist can have anywhere from 0 to
    // max_capacity_ slots to put link list chains into.
    info.capacity = 16 * objs_to_move;

    // Limit each size class cache to at most 1MB of objects or one entry,
    // whichever is greater. Total transfer cache memory used across all
    // size classes then can't be greater than approximately
    // 1MB * kMaxNumTransferEntries.
    max_capacity_ = std::min<size_t>(
        max_capacity_,
        std::max<size_t>(objs_to_move, (1024 * 1024) / (bytes * objs_to_move) *
                                           objs_to_move));
    info.capacity = std::min(info.capacity, max_capacity_);
    slots_ = reinterpret_cast<void **>(
        Static::arena()->Alloc(max_capacity_ * sizeof(void *)));
  }
  SetSlotInfo(info);
}

bool TransferCache::MakeCacheSpace(int N) {
  auto info = slot_info_.load(std::memory_order_relaxed);
  // Is there room in the cache?
  if (info.used + N <= info.capacity) return true;
  // Check if we can expand this cache?
  if (info.capacity + N > max_capacity_) return false;

  int to_evict = gEvictionManager.DetermineSizeClassToEvict();
  if (to_evict == freelist_.size_class()) return false;

  // Release the held lock before the other instance tries to grab its lock.
  lock_.Unlock();
  bool made_space = Static::transfer_cache()[to_evict].ShrinkCache();
  lock_.Lock();

  if (!made_space) return false;

  // Succeeded in evicting, we're going to make our cache larger.  However, we
  // may have dropped and re-acquired the lock, so the cache_size may have
  // changed.  Therefore, check and verify that it is still OK to increase the
  // cache_size.
  info = slot_info_.load(std::memory_order_relaxed);
  if (info.capacity + N > max_capacity_) return false;
  info.capacity += N;
  SetSlotInfo(info);
  return true;
}

bool TransferCache::ShrinkCache() {
  auto info = slot_info_.load(std::memory_order_relaxed);

  // Start with a quick check without taking a lock.
  if (info.capacity == 0) return false;

  int N = Static::sizemap()->num_objects_to_move(freelist_.size_class());

  void *to_free[kMaxObjectsToMove];
  int num_to_free;
  {
    absl::base_internal::SpinLockHolder h(&lock_);

    // Fetch while holding the lock in case they changed.
    info = slot_info_.load(std::memory_order_relaxed);

    if (info.capacity == 0) return false;
    if (!arbitrary_transfer_ && info.capacity < N) return false;

    N = std::min(N, info.capacity);
    int unused = info.capacity - info.used;
    if (N <= unused) {
      info.capacity -= N;
      SetSlotInfo(info);
      return true;
    }

    num_to_free = N - unused;
    info.capacity -= N;
    info.used -= num_to_free;
    SetSlotInfo(info);
    // Our internal slot array may get overwritten as soon as we drop the lock,
    // so copy the items to free to an on stack buffer.
    memcpy(to_free, GetSlot(info.used), sizeof(void *) * num_to_free);
  }

  // Access the freelist without holding the lock.
  freelist_.InsertRange(to_free, num_to_free);
  return true;
}

void TransferCache::InsertRange(absl::Span<void *> batch, int N) {
  const int B = Static::sizemap()->num_objects_to_move(freelist_.size_class());
  ASSERT(0 < N && N <= B);
  auto info = slot_info_.load(std::memory_order_relaxed);
  if (N == B && info.used + N <= max_capacity_) {
    absl::base_internal::SpinLockHolder h(&lock_);
    if (MakeCacheSpace(N)) {
      // MakeCacheSpace can drop the lock, so refetch
      info = slot_info_.load(std::memory_order_relaxed);
      info.used += N;
      SetSlotInfo(info);

      void **entry = GetSlot(info.used - N);
      memcpy(entry, batch.data(), sizeof(void *) * N);
      tracking::Report(kTCInsertHit, freelist_.size_class(), 1);
      return;
    }
  } else if (arbitrary_transfer_) {
    absl::base_internal::SpinLockHolder h(&lock_);
    MakeCacheSpace(N);
    // MakeCacheSpace can drop the lock, so refetch
    info = slot_info_.load(std::memory_order_relaxed);
    int unused = info.capacity - info.used;
    if (N < unused) {
      info.used += N;
      SetSlotInfo(info);
      void **entry = GetSlot(info.used - N);
      memcpy(entry, batch.data(), sizeof(void *) * N);
      tracking::Report(kTCInsertHit, freelist_.size_class(), 1);
      return;
    }
    // We could not fit the entire batch into the transfer cache
    // so send the batch to the freelist and also take some elements from
    // the transfer cache so that we amortise the cost of accessing spans
    // in the freelist. Only do this if caller has sufficient space in
    // batch.
    // First of all fill up the rest of the batch with elements from the
    // transfer cache.
    int extra = B - N;
    if (N > 1 && extra > 0 && info.used > 0 && batch.size() >= B) {
      // Take at most all the objects present
      extra = std::min(extra, info.used);
      ASSERT(extra + N <= kMaxObjectsToMove);
      info.used -= extra;
      SetSlotInfo(info);

      void **entry = GetSlot(info.used);
      memcpy(batch.data() + N, entry, sizeof(void *) * extra);
      N += extra;
#ifndef NDEBUG
      int rest = batch.size() - N - 1;
      if (rest > 0) {
        memset(batch.data() + N, 0x3f, rest * sizeof(void *));
      }
#endif
    }
  }
  tracking::Report(kTCInsertMiss, freelist_.size_class(), 1);
  freelist_.InsertRange(batch.data(), N);
}

int TransferCache::RemoveRange(void **batch, int N) {
  ASSERT(N > 0);
  const int B = Static::sizemap()->num_objects_to_move(freelist_.size_class());
  int fetch = 0;
  auto info = slot_info_.load(std::memory_order_relaxed);
  if (N == B && info.used >= N) {
    absl::base_internal::SpinLockHolder h(&lock_);
    // Refetch with the lock
    info = slot_info_.load(std::memory_order_relaxed);
    if (info.used >= N) {
      info.used -= N;
      SetSlotInfo(info);
      void **entry = GetSlot(info.used);
      memcpy(batch, entry, sizeof(void *) * N);
      tracking::Report(kTCRemoveHit, freelist_.size_class(), 1);
      return N;
    }
  } else if (arbitrary_transfer_ && info.used >= 0) {
    absl::base_internal::SpinLockHolder h(&lock_);
    // Refetch with the lock
    info = slot_info_.load(std::memory_order_relaxed);

    fetch = std::min(N, info.used);
    info.used -= fetch;
    SetSlotInfo(info);
    void **entry = GetSlot(info.used);
    memcpy(batch, entry, sizeof(void *) * fetch);
    tracking::Report(kTCRemoveHit, freelist_.size_class(), 1);
    if (fetch == N) return N;
  }
  tracking::Report(kTCRemoveMiss, freelist_.size_class(), 1);
  return freelist_.RemoveRange(batch + fetch, N - fetch) + fetch;
}

size_t TransferCache::tc_length() {
  return static_cast<size_t>(slot_info_.load(std::memory_order_relaxed).used);
}

#endif
}  // namespace tcmalloc
<|endoftext|>


<commit_before>//
//  Player.cpp
//  CheckersProject
//
//  Created by Benjamin Emdon on 2016-02-13.
//  Copyright © 2016 Ben Emdon.
//

#include "../include/Player.h"
#include "../include/CheckersBoard.h"
#include "../include/Button.h"
#include "../include/GameState.h"

Player::Player(bool topSide, CheckersBoard *board, Button buttons[]){
    Board = board;
    boardButtons = buttons;
    initTeam(topSide);
    if (topSide) {
        ONE = 1;
        turn = false;
    }
    else{
        ONE = -1;
        turn = true;
    }
}

Player::~Player(){
    team.clear();
    delete Board;
    Board = NULL;
    delete boardButtons;
    boardButtons = NULL;
}

void Player::initTeam(bool topSide) {
    if (topSide) {
        //----------------------------BLACK TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 1;
        team[0].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 3;
        team[1].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 5;
        team[2].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 7;
        team[3].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 0;
        team[4].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 2;
        team[5].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 4;
        team[6].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 6;
        team[7].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 1;
        team[8].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 3;
        team[9].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 5;
        team[10].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 7;
        team[11].y = 2;

        //Sets TEAM_NUMBER
        TEAM_NUMBER = BLACK_PIECE;
        ENEMY_TEAM_NUMBER = RED_PIECE;
    }
    else {
        //-----------------------------RED TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 0;
        team[0].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 2;
        team[1].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 4;
        team[2].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 6;
        team[3].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 1;
        team[4].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 3;
        team[5].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 5;
        team[6].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 7;
        team[7].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 0;
        team[8].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 2;
        team[9].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 4;
        team[10].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 6;
        team[11].y = 5;

        //Sets TEAM_NUMBER
        TEAM_NUMBER = RED_PIECE;
        ENEMY_TEAM_NUMBER = BLACK_PIECE;
    }

        // Update Virtual board after init //

    for (int teamIndex = 0; teamIndex < teamSize; teamIndex++) {
        Board->virtualBoard[team[teamIndex].x][team[teamIndex].y] = topSide + 1;
    }
}

bool Player::makeMove(SDL_Event *){
    return false;
}

void Player::movePiece(int teamIndex, int newX, int newY){
    //cout<<"enter move func"<<endl;
    // Moves piece
    if (abs(newX - team[teamIndex].x) == 2 && abs(newY - team[teamIndex].y) == 2) {
        killPiece(abs(newX + team[teamIndex].x)/2, abs(newY + team[teamIndex].y)/2);

    }
    //cout<<team[teamIndex].x<<","<<team[teamIndex].y<<"  New place:"<<newX<<","<<newY<<endl;
    Board->virtualBoard[newX][newY] = Board->virtualBoard[team[teamIndex].x][team[teamIndex].y];
    Board->virtualBoard[team[teamIndex].x][team[teamIndex].y] = EMPTY_PIECE;
    team[teamIndex].x = newX;
    team[teamIndex].y = newY;
    // Prints virtualBoard at end of move
    cout<<*Board<<endl;
}

void Player::killPiece(int x, int y) {
    Board->virtualBoard[x][y] = EMPTY_PIECE;
}

void Player::updateTeam() {
    for(int index=0;index<teamSize;index++){
        if (Board->virtualBoard[team[index].x][team[index].y] != TEAM_NUMBER) {
            team.erase(team.begin()+index);
            teamSize--;
            index--;
            cout<<"Team:\t"<<TEAM_NUMBER<<"\thas a TeamSize:\t" << teamSize <<endl;
        }
    }
}

int Player::pieceTeamIndexByXY(int x, int y) {
    int index=0;
    for(;index<teamSize;index++){
        if((team[index].x == x) && (team[index].y == y)){
            break;
        }
    }
    return index;
}
<commit_msg>Added make king -buggy<commit_after>//
//  Player.cpp
//  CheckersProject
//
//  Created by Benjamin Emdon on 2016-02-13.
//  Copyright © 2016 Ben Emdon.
//

#include "../include/Player.h"
#include "../include/CheckersBoard.h"
#include "../include/Button.h"
#include "../include/GameState.h"

Player::Player(bool topSide, CheckersBoard *board, Button buttons[]){
    Board = board;
    boardButtons = buttons;
    initTeam(topSide);
    if (topSide) {
        ONE = 1;
        turn = false;
    }
    else{
        ONE = -1;
        turn = true;
    }
}

Player::~Player(){
    team.clear();
    delete Board;
    Board = NULL;
    delete boardButtons;
    boardButtons = NULL;
}

void Player::initTeam(bool topSide) {
    if (topSide) {
        //----------------------------BLACK TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 1;
        team[0].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 3;
        team[1].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 5;
        team[2].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 7;
        team[3].y = 0;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 0;
        team[4].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 2;
        team[5].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 4;
        team[6].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 6;
        team[7].y = 1;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 1;
        team[8].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 3;
        team[9].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 5;
        team[10].y = 2;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 7;
        team[11].y = 2;

        //Sets TEAM_NUMBER
        TEAM_NUMBER = BLACK_PIECE;
        ENEMY_TEAM_NUMBER = RED_PIECE;
    }
    else {
        //-----------------------------RED TEAM----------------------------\\
        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 0
        team[0].x = 0;
        team[0].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 1
        team[1].x = 2;
        team[1].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 2
        team[2].x = 4;
        team[2].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 3
        team[3].x = 6;
        team[3].y = 7;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 4
        team[4].x = 1;
        team[4].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 5
        team[5].x = 3;
        team[5].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 6
        team[6].x = 5;
        team[6].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 7
        team[7].x = 7;
        team[7].y = 6;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 8
        team[8].x = 0;
        team[8].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 9
        team[9].x = 2;
        team[9].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 10
        team[10].x = 4;
        team[10].y = 5;

        //Push back new chip created with default constructor.
        team.push_back(Piece());
        //Vector now has 1 element @ index 11
        team[11].x = 6;
        team[11].y = 5;

        //Sets TEAM_NUMBER
        TEAM_NUMBER = RED_PIECE;
        ENEMY_TEAM_NUMBER = BLACK_PIECE;
    }

        // Update Virtual board after init //

    for (int teamIndex = 0; teamIndex < teamSize; teamIndex++) {
        Board->virtualBoard[team[teamIndex].x][team[teamIndex].y] = topSide + 1;
    }
}

bool Player::makeMove(SDL_Event *){
    return false;
}

void Player::movePiece(int teamIndex, int newX, int newY){
    //cout<<"enter move func"<<endl;
    // Moves piece
    if (abs(newX - team[teamIndex].x) == 2 && abs(newY - team[teamIndex].y) == 2) {
        killPiece(abs(newX + team[teamIndex].x)/2, abs(newY + team[teamIndex].y)/2);

    }
    //cout<<team[teamIndex].x<<","<<team[teamIndex].y<<"  New place:"<<newX<<","<<newY<<endl;
    Board->virtualBoard[newX][newY] = Board->virtualBoard[team[teamIndex].x][team[teamIndex].y];
    Board->virtualBoard[team[teamIndex].x][team[teamIndex].y] = EMPTY_PIECE;
    team[teamIndex].x = newX;
    team[teamIndex].y = newY;
    // Prints virtualBoard at end of move
    cout<<*Board<<endl;
}

void Player::killPiece(int x, int y) {
    Board->virtualBoard[x][y] = EMPTY_PIECE;
}

void Player::updateTeam() {
    int yToMakeKing = 8 * !topSide;
    for(int index=0;index<teamSize;index++){
        if (Board->virtualBoard[team[index].x][team[index].y] != TEAM_NUMBER) {
            team.erase(team.begin()+index);
            teamSize--;
            index--;
            cout<<"Team:\t"<<TEAM_NUMBER<<"\thas a TeamSize:\t" << teamSize <<endl;
        }
        if (team[index].y == yToMakeKing) {
            team[index].makeKing();
            Board->virtualBoard[team[index].x][team[index].y] += 2;
        }
    }
}

int Player::pieceTeamIndexByXY(int x, int y) {
    int index=0;
    for(;index<teamSize;index++){
        if((team[index].x == x) && (team[index].y == y)){
            break;
        }
    }
    return index;
}
<|endoftext|>


<commit_before>#include <config.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <netcdf.h>

using namespace std;

#ifdef EXTRA_TESTS
#define MEGABYTE 1048576
void
get_mem_used2(int *mem_used)
{
   char buf[30];
   FILE *pf;
   size_t page_size = 4092; /* For spock... */
   unsigned size; /*       total program size */
   unsigned resident;/*   resident set size */
   unsigned share;/*      shared pages */
   unsigned text;/*       text (code) */
   unsigned lib;/*        library */
   unsigned data;/*       data/stack */
   /*unsigned dt;          dirty pages (unused in Linux 2.6)*/

   snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
   if ((pf = fopen(buf, "r")))
   {
      fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share,
	     &text, &lib, &data);
      *mem_used = (data * page_size) / MEGABYTE;
   }
   else
      *mem_used = -1;
  fclose(pf);
}
#endif /* EXTRA_TESTS */

//Exception class
class NcErrorException : public exception
{
public:
   NcErrorException(const string& descr) throw(): exception(), _descr(descr)  {};
   ~NcErrorException() throw() {};

   const char* what() const throw() { ostringstream err; err << "NcErrorException: " << _descr;  return err.str().c_str();   };

private:
   string _descr;
};

void handle_error(int status) {
   if (status != NC_NOERR) {
      throw NcErrorException(nc_strerror(status));
   }
};

/******MAIN********/
int main(int argc, char** argv)
{
   int NUMVARS = 1;
   size_t NUMREC=10000;
   int fileId, dimId, varId[NUMVARS];
   string filename("tst_many_writes.nc");

   cout << "\n*** Testing netCDF-4 file with user-provided test (thanks Marica!)\n";

   try{
      //create the netcdf-4 file
      handle_error(nc_create(filename.c_str(), NC_NETCDF4, &fileId));

      //define the unlimited dimension "rec"
      handle_error(nc_def_dim(fileId, "rec", NC_UNLIMITED, &dimId)); //--> Segmentation Fault
      //handle_error ( nc_def_dim(fileId, "rec", NUMREC, &dimId) );  //--> Good!!

      int dimids[1] = {dimId};

      //define NUMVARS variables named field_%i using a loop
      for (int v = 0; v < NUMVARS; v++)
      {
      	 size_t chunkSize[1] = {100000};
      	 ostringstream varName; varName << "field_" << v;
      	 handle_error(nc_def_var(fileId, varName.str().c_str(), NC_DOUBLE, 1, dimids , &varId[v]));
      	 handle_error(nc_def_var_chunking(fileId, varId[v], NC_CHUNKED, chunkSize));
      }
      handle_error (nc_enddef(fileId));

      //write data to the NUMVARS variables using nc_put_var1_double
      double data = 100;
      size_t start[1];
      size_t count[1] = {1};
      char charName[NC_MAX_NAME+1];

      for (int v = 0; v < NUMVARS; v++)
      {
      	 handle_error(nc_inq_varname(fileId, varId[v], charName));
	 cout << "var " << v << "\n";
      	 for (size_t start = 0; start < NUMREC; start++)
      	 {
#ifdef EXTRA_TESTS
	    if (start % 1000 == 0)
	    {
	       int mem_used;
	       get_mem_used2(&mem_used);
	       cout << mem_used << "\n";
	    }
#endif /* EXTRA_TESTS */
      	    handle_error(nc_put_vara_double(fileId, varId[v], &start, count, &data));
      	 }
      }

      //close file
      handle_error(nc_close(fileId));
      cout << "*** nctst SUCCESS!\n";
   }
   catch(exception &ex) //exception handling
   {
      cerr << "Exception caught: " << ex.what() << endl;
      cout << "*** nctst FAILURE!\n";
      return -1;
   }
}
<commit_msg>fixed test so that solaris would compile it<commit_after>#include <config.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <netcdf.h>

using namespace std;

#ifdef EXTRA_TESTS
#define MEGABYTE 1048576
void
get_mem_used2(int *mem_used)
{
   char buf[30];
   FILE *pf;
   size_t page_size = 4092; /* For spock... */
   unsigned size; /*       total program size */
   unsigned resident;/*   resident set size */
   unsigned share;/*      shared pages */
   unsigned text;/*       text (code) */
   unsigned lib;/*        library */
   unsigned data;/*       data/stack */
   /*unsigned dt;          dirty pages (unused in Linux 2.6)*/

   snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
   if ((pf = fopen(buf, "r")))
   {
      fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share,
	     &text, &lib, &data);
      *mem_used = (data * page_size) / MEGABYTE;
   }
   else
      *mem_used = -1;
  fclose(pf);
}
#endif /* EXTRA_TESTS */

//Exception class
class NcErrorException : public exception
{
public:
   NcErrorException(const string& descr) throw(): exception(), _descr(descr)  {};
   ~NcErrorException() throw() {};

   const char* what() const throw() { ostringstream err; err << "NcErrorException: " << _descr;  return err.str().c_str();   };

private:
   string _descr;
};

void handle_error(int status) {
   if (status != NC_NOERR) {
      throw NcErrorException(nc_strerror(status));
   }
};

/******MAIN********/
int main(int argc, char** argv)
{
   int NUMVARS = 1;
   size_t NUMREC=10000;
   int fileId, dimId, varId[1];
   string filename("tst_many_writes.nc");

   cout << "\n*** Testing netCDF-4 file with user-provided test (thanks Marica!)\n";

   try{
      //create the netcdf-4 file
      handle_error(nc_create(filename.c_str(), NC_NETCDF4, &fileId));

      //define the unlimited dimension "rec"
      handle_error(nc_def_dim(fileId, "rec", NC_UNLIMITED, &dimId)); //--> Segmentation Fault
      //handle_error ( nc_def_dim(fileId, "rec", NUMREC, &dimId) );  //--> Good!!

      int dimids[1] = {dimId};

      //define NUMVARS variables named field_%i using a loop
      for (int v = 0; v < NUMVARS; v++)
      {
      	 size_t chunkSize[1] = {100000};
      	 ostringstream varName; varName << "field_" << v;
      	 handle_error(nc_def_var(fileId, varName.str().c_str(), NC_DOUBLE, 1, dimids , &varId[v]));
      	 handle_error(nc_def_var_chunking(fileId, varId[v], NC_CHUNKED, chunkSize));
      }
      handle_error (nc_enddef(fileId));

      //write data to the NUMVARS variables using nc_put_var1_double
      double data = 100;
      size_t start[1];
      size_t count[1] = {1};
      char charName[NC_MAX_NAME+1];

      for (int v = 0; v < NUMVARS; v++)
      {
      	 handle_error(nc_inq_varname(fileId, varId[v], charName));
	 cout << "var " << v << "\n";
      	 for (size_t start = 0; start < NUMREC; start++)
      	 {
#ifdef EXTRA_TESTS
	    if (start % 1000 == 0)
	    {
	       int mem_used;
	       get_mem_used2(&mem_used);
	       cout << mem_used << "\n";
	    }
#endif /* EXTRA_TESTS */
      	    handle_error(nc_put_vara_double(fileId, varId[v], &start, count, &data));
      	 }
      }

      //close file
      handle_error(nc_close(fileId));
      cout << "*** nctst SUCCESS!\n";
   }
   catch(exception &ex) //exception handling
   {
      cerr << "Exception caught: " << ex.what() << endl;
      cout << "*** nctst FAILURE!\n";
      return -1;
   }
}
<|endoftext|>


<commit_before><commit_msg>Make sure to ignore trailing empty rows in all places.<commit_after><|endoftext|>


<commit_before>/*
  NUI3 - C++ cross-platform GUI framework for OpenGL based applications
  Copyright (C) 2002-2003 Sebastien Metrot

  licence: see nui3/LICENCE.TXT
*/

#include "nui.h"
#include NGL_CONFIG_H

#ifdef HAVE_LIBPNG

#include "nglImage.h"
#include "nglImagePNGCodec.h"
#include "png.h"
#include "nglIStream.h"
#include "nglOStream.h"

class nglImagePNGCodec : public nglImageCodec
{
public:
  nglImagePNGCodec();
  virtual ~nglImagePNGCodec();
  virtual bool Probe(nglIStream* pIStream);
  virtual bool Feed(nglIStream* pOStream);
  virtual bool Save(nglOStream* pOStream);
  virtual float GetCompletion();
private:
  png_structp png_ptr;
  png_infop info_ptr;
  png_bytep old_row;
  png_byte** mpRowPointers;

  int initialize_png_reader();
  /* A code fragment that you call as you receive blocks of data */
  int process_data(png_bytep buffer, png_uint_32 length);
  /* This function is called (as set by png_set_progressive_read_fn() above) when enough data
    has been supplied so all of the header has been read. */
  friend void info_callback(png_structp png_ptr, png_infop info);
  /* This function is called when each row of image data is complete */
  friend void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass);
  friend void end_callback(png_structp png_ptr, png_infop info);

  void InfoCallback(png_structp png_ptr, png_infop info_ptr);

};

nglImageCodec* nglImagePNGCodecInfo::CreateInstance()
{
  return new nglImagePNGCodec();
}

nglImagePNGCodec::nglImagePNGCodec()
{
  mpRowPointers = NULL;
  png_ptr=NULL;
  info_ptr=NULL;
  old_row=NULL;
}

nglImagePNGCodec::~nglImagePNGCodec()
{
  if (mpRowPointers)
    free (mpRowPointers);
  mpRowPointers=NULL;

  if (png_ptr && info_ptr)
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  png_ptr =NULL;
  info_ptr = NULL;

}

bool nglImagePNGCodec::Probe(nglIStream* pIStream)
{
  if (pIStream->Available(4)) // A not so robust png detection routine...
  {
    char buffer[4];
    if (!pIStream->Peek(buffer,1,4))
      return false;
    if (buffer[1]=='P' &&
        buffer[2]=='N' &&
        buffer[3]=='G')
    {
      initialize_png_reader();
      return true;
    }
  }
  return false;
}

/* This function is called (as set by
  png_set_progressive_read_fn() above) when enough data
  has been supplied so all of the header has been
  read.
  */
void info_callback(png_structp png_ptr, png_infop info_ptr)
{
  /* Do any setup here, including setting any of
    the transformations mentioned in the Reading
    PNG files section.  For now, you _must_ call
    either png_start_read_image() or
    png_read_update_info() after all the
    transformations are set (even if you don't set
    any).  You may start getting rows before
    png_process_data() returns, so this is your
    last chance to prepare for that.
      */
  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));
  pCodec->InfoCallback(png_ptr, info_ptr);
}

/* This function is called when each row of image
data is complete */
void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass)
{
  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));

  /* If the image is interlaced, and you turned
    on the interlace handler, this function will
    be called for every row in every pass.  Some
    of these rows will not be changed from the
    previous pass.  When the row is not changed,
    the new_row variable will be NULL.  The rows
    and passes are called in order, so you don't
    really need the row_num and pass, but I'm
    supplying them because it may make your life
    easier.

    For the non-NULL rows of interlaced images,
    you must call png_progressive_combine_row()
    passing in the row and the old row.  You can
    call this function for NULL rows (it will just
    return) and for non-interlaced images (it just
    does the memcpy for you) if it will make the
    code easier.  Thus, you can just do this for
    all cases:
    */

  if (pCodec->old_row && new_row)
    png_progressive_combine_row(png_ptr, pCodec->old_row, new_row);
  pCodec->old_row = new_row;

  if (new_row)
  {
    char*buffer=pCodec->mpImage->GetBuffer();
    uint size=pCodec->mpImage->GetBytesPerLine();
    buffer+= row_num * size;
    memcpy(buffer,new_row,size);
  }

  /* where old_row is what was displayed for
    previously for the row.  Note that the first
    pass (pass == 0, really) will completely cover
    the old row, so the rows do not have to be
    initialized.  After the first pass (and only
    for interlaced images), you will have to pass
    the current row, and the function will combine
    the old row and the new row.
  */
}

void end_callback(png_structp png_ptr, png_infop info)
{
/* This function is called after the whole image
  has been read, including any chunks after the
  image (up to and including the IEND).  You
  will usually have the same info chunk as you
  had in the header, although some data may have
  been added to the comments and time fields.

  Most people won't do much here, perhaps setting
  a flag that marks the image as finished.
  */
//  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));
}

/*  An example code fragment of how you would initialize the progressive reader in your application. */
int nglImagePNGCodec::initialize_png_reader()
{
  png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
  if (!png_ptr)
    return -1;
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    return -1;
  }

  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return -1;
  }

#ifdef _WIN32_
  double ScreenGamma = 2.2 / 1.0;
#elif (defined _UNIX_)
  double ScreenGamma = 2.2 / 1.7;
#elif (defined _CARBON_)
  double ScreenGamma = 1.8;
#endif //ifdef _WIN32_
  double FileGamma = 1.0 / 2.2;
  if (png_get_gAMA(png_ptr, info_ptr, &FileGamma))
    png_set_gamma(png_ptr, ScreenGamma, FileGamma);
  else
    png_set_gamma(png_ptr, ScreenGamma, 1.0 / 2.2);

  /* This one's new.  You can provide functions to be called when the header info is valid,
    when each row is completed, and when the image is finished.  If you aren't using all functions,
    you can specify NULL parameters.  Even when all three functions are NULL, you need to call
    png_set_progressive_read_fn().  You can use any struct as the user_ptr (cast to a void pointer
    for the function call), and retrieve the pointer from inside the callbacks using the function

      png_get_progressive_ptr(png_ptr);

        which will return a void pointer, which you have
        to cast appropriately.
    */
  png_set_progressive_read_fn(png_ptr, (void *)this , info_callback, row_callback, end_callback);

  return 0;
}

/* A code fragment that you call as you receive blocks of data */
int nglImagePNGCodec::process_data(png_bytep buffer, png_uint_32 length)
{

  if (setjmp(png_jmpbuf( png_ptr )))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return -1;
  }

  /* This one's new also.  Simply give it a chunk
    of data from the file stream (in order, of
    course).  On machines with segmented memory
    models machines, don't give it any more than
    64K.  The library seems to run fine with sizes
    of 4K. Although you can give it much less if
    necessary (I assume you can give it chunks of
    1 byte, I haven't tried less then 256 bytes
    yet).  When this function returns, you may
    want to display any rows that were generated
    in the row callback if you don't already do
    so there.
    */
  png_process_data(png_ptr, info_ptr, buffer, length);
  return 0;
}

void nglImagePNGCodec::InfoCallback(png_structp png_ptr, png_infop info_ptr)
{
  nglImageInfo imginfo;

 short int color_type = png_get_color_type(png_ptr, info_ptr);

  // expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
  // transparency chunks to full alpha channel; strip 16-bit-per-sample
  // images to 8 bits per sample; and convert grayscale to RGB[A]

  if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_expand(png_ptr);
  if (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth( png_ptr, info_ptr ) < 8)
      png_set_expand(png_ptr);
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
      png_set_expand(png_ptr);
//      if (GetBitDepth() == 16)
//          png_set_strip_16(mpPngData);
//  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
//      png_set_gray_to_rgb(png_ptr);

  if (png_get_interlace_type(png_ptr,info_ptr)!=PNG_INTERLACE_NONE)
    png_set_interlace_handling(png_ptr);

  png_read_update_info(png_ptr, info_ptr);

  imginfo.mWidth = png_get_image_width( png_ptr, info_ptr );
  imginfo.mHeight = png_get_image_height( png_ptr, info_ptr );
  imginfo.mBufferFormat = eImageFormatRaw;
  if (png_get_channels( png_ptr, info_ptr )==1)
    imginfo.mPixelFormat = eImagePixelLum;
  else if (png_get_channels( png_ptr, info_ptr )==2)
    imginfo.mPixelFormat = eImagePixelLumA;
  else if (png_get_channels( png_ptr, info_ptr )==3)
    imginfo.mPixelFormat = eImagePixelRGB;
  else if (png_get_channels( png_ptr, info_ptr )==4)
    imginfo.mPixelFormat = eImagePixelRGBA;

  imginfo.mBitDepth = png_get_bit_depth( png_ptr, info_ptr ) * png_get_channels( png_ptr, info_ptr );
  imginfo.mBytesPerPixel = imginfo.mBitDepth / 8;
  imginfo.mBytesPerLine = imginfo.mBytesPerPixel * imginfo.mWidth;

  SendInfo(imginfo);

  mpRowPointers = (png_byte**) malloc(imginfo.mHeight * sizeof(png_byte*));

  uint i;
  for(i = 0; i < imginfo.mHeight; i++)
    mpRowPointers[i] = (png_byte*)mpImage->GetBuffer()
                     + (imginfo.mHeight - i - 1) * imginfo.mBytesPerPixel * imginfo.mWidth;

  png_start_read_image(png_ptr);
}

bool nglImagePNGCodec::Feed(nglIStream* pIStream)
{
  nglFileSize size=pIStream->Available();
  char* buffer=new char[(size_t)size];
  pIStream->Read(buffer,(size_t)size,1);
  process_data((unsigned char*)buffer, (size_t)size);
  delete[] buffer;
  return true;
}

#ifdef _CARBON_
void nglWritePNG( png_structp png_ptr, png_bytep data, long unsigned int length )
#else
void nglWritePNG( png_structp png_ptr, png_bytep data, unsigned int length )
#endif
{
  ((nglOStream*)(png_get_io_ptr(png_ptr)))->Write( (png_byte *)data, (long int) length, 1 );
}

void nglFlushPNG( png_structp png_ptr )
{
}

bool nglImagePNGCodec::Save(nglOStream* pOStream)
{
  png_structp png_ptr = png_create_write_struct
                          ( PNG_LIBPNG_VER_STRING,
                            (png_voidp)NULL,
                            NULL,
                            NULL);
  if (!png_ptr)
    return false;

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    return false;
  }

  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_write_struct(&png_ptr, &info_ptr);
    return false;
  }

  png_set_write_fn( png_ptr, (void*)pOStream, nglWritePNG, nglFlushPNG);

/* set the zlib compression level */
  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);

  /* set other zlib parameters */
  nglImageInfo Info;
  mpImage->GetInfo(Info);

  png_set_IHDR( png_ptr, info_ptr, Info.mWidth, Info.mHeight, Info.mBitDepth/Info.mBytesPerPixel,
                Info.mBytesPerPixel == 4 ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
                PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
              );

  uint i;
  png_byte **row_pointers;
  row_pointers = (png_byte**) malloc(Info.mHeight * sizeof(png_byte*));

  for(i = 0; i < Info.mHeight; i++)
    row_pointers[i] = (unsigned char*)(Info.mpBuffer + i * Info.mBytesPerLine);

  png_write_info(png_ptr, info_ptr);

  /* set up the transformations:  for now, just pack low-bit-depth pixels
  * into bytes (one, two or four pixels per byte) */

  png_set_packing(png_ptr);

  png_write_image (png_ptr, row_pointers);
  png_write_end(png_ptr, info_ptr); // Write the end chunck of the image.
  png_destroy_write_struct( &png_ptr, &info_ptr );
  free(row_pointers);
  return true;
}

float nglImagePNGCodec::GetCompletion()
{
  return 0;
}

#endif // HAVE_LIBPNG
<commit_msg>hopefully better png gamma on the mac<commit_after>/*
  NUI3 - C++ cross-platform GUI framework for OpenGL based applications
  Copyright (C) 2002-2003 Sebastien Metrot

  licence: see nui3/LICENCE.TXT
*/

#include "nui.h"
#include NGL_CONFIG_H

#ifdef HAVE_LIBPNG

#include "nglImage.h"
#include "nglImagePNGCodec.h"
#include "png.h"
#include "nglIStream.h"
#include "nglOStream.h"

class nglImagePNGCodec : public nglImageCodec
{
public:
  nglImagePNGCodec();
  virtual ~nglImagePNGCodec();
  virtual bool Probe(nglIStream* pIStream);
  virtual bool Feed(nglIStream* pOStream);
  virtual bool Save(nglOStream* pOStream);
  virtual float GetCompletion();
private:
  png_structp png_ptr;
  png_infop info_ptr;
  png_bytep old_row;
  png_byte** mpRowPointers;

  int initialize_png_reader();
  /* A code fragment that you call as you receive blocks of data */
  int process_data(png_bytep buffer, png_uint_32 length);
  /* This function is called (as set by png_set_progressive_read_fn() above) when enough data
    has been supplied so all of the header has been read. */
  friend void info_callback(png_structp png_ptr, png_infop info);
  /* This function is called when each row of image data is complete */
  friend void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass);
  friend void end_callback(png_structp png_ptr, png_infop info);

  void InfoCallback(png_structp png_ptr, png_infop info_ptr);

};

nglImageCodec* nglImagePNGCodecInfo::CreateInstance()
{
  return new nglImagePNGCodec();
}

nglImagePNGCodec::nglImagePNGCodec()
{
  mpRowPointers = NULL;
  png_ptr=NULL;
  info_ptr=NULL;
  old_row=NULL;
}

nglImagePNGCodec::~nglImagePNGCodec()
{
  if (mpRowPointers)
    free (mpRowPointers);
  mpRowPointers=NULL;

  if (png_ptr && info_ptr)
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
  png_ptr =NULL;
  info_ptr = NULL;

}

bool nglImagePNGCodec::Probe(nglIStream* pIStream)
{
  if (pIStream->Available(4)) // A not so robust png detection routine...
  {
    char buffer[4];
    if (!pIStream->Peek(buffer,1,4))
      return false;
    if (buffer[1]=='P' &&
        buffer[2]=='N' &&
        buffer[3]=='G')
    {
      initialize_png_reader();
      return true;
    }
  }
  return false;
}

/* This function is called (as set by
  png_set_progressive_read_fn() above) when enough data
  has been supplied so all of the header has been
  read.
  */
void info_callback(png_structp png_ptr, png_infop info_ptr)
{
  /* Do any setup here, including setting any of
    the transformations mentioned in the Reading
    PNG files section.  For now, you _must_ call
    either png_start_read_image() or
    png_read_update_info() after all the
    transformations are set (even if you don't set
    any).  You may start getting rows before
    png_process_data() returns, so this is your
    last chance to prepare for that.
      */
  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));
  pCodec->InfoCallback(png_ptr, info_ptr);
}

/* This function is called when each row of image
data is complete */
void row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass)
{
  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));

  /* If the image is interlaced, and you turned
    on the interlace handler, this function will
    be called for every row in every pass.  Some
    of these rows will not be changed from the
    previous pass.  When the row is not changed,
    the new_row variable will be NULL.  The rows
    and passes are called in order, so you don't
    really need the row_num and pass, but I'm
    supplying them because it may make your life
    easier.

    For the non-NULL rows of interlaced images,
    you must call png_progressive_combine_row()
    passing in the row and the old row.  You can
    call this function for NULL rows (it will just
    return) and for non-interlaced images (it just
    does the memcpy for you) if it will make the
    code easier.  Thus, you can just do this for
    all cases:
    */

  if (pCodec->old_row && new_row)
    png_progressive_combine_row(png_ptr, pCodec->old_row, new_row);
  pCodec->old_row = new_row;

  if (new_row)
  {
    char*buffer=pCodec->mpImage->GetBuffer();
    uint size=pCodec->mpImage->GetBytesPerLine();
    buffer+= row_num * size;
    memcpy(buffer,new_row,size);
  }

  /* where old_row is what was displayed for
    previously for the row.  Note that the first
    pass (pass == 0, really) will completely cover
    the old row, so the rows do not have to be
    initialized.  After the first pass (and only
    for interlaced images), you will have to pass
    the current row, and the function will combine
    the old row and the new row.
  */
}

void end_callback(png_structp png_ptr, png_infop info)
{
/* This function is called after the whole image
  has been read, including any chunks after the
  image (up to and including the IEND).  You
  will usually have the same info chunk as you
  had in the header, although some data may have
  been added to the comments and time fields.

  Most people won't do much here, perhaps setting
  a flag that marks the image as finished.
  */
//  nglImagePNGCodec* pCodec=(nglImagePNGCodec*)(png_get_progressive_ptr(png_ptr));
}

/*  An example code fragment of how you would initialize the progressive reader in your application. */
int nglImagePNGCodec::initialize_png_reader()
{
  png_ptr = png_create_read_struct
    (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL);
  if (!png_ptr)
    return -1;
  info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    return -1;
  }

  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return -1;
  }

#ifdef _WIN32_
  double ScreenGamma = 2.2 / 1.0;
#elif (defined _UNIX_)
  double ScreenGamma = 2.2 / 1.7;
#elif (defined _CARBON_)
  double ScreenGamma = 2.2 / 1.45;
#endif //ifdef _WIN32_
  double FileGamma = 1.0 / 2.2;
  if (png_get_gAMA(png_ptr, info_ptr, &FileGamma))
    png_set_gamma(png_ptr, ScreenGamma, FileGamma);
  else
    png_set_gamma(png_ptr, ScreenGamma, 1.0 / 2.2);

  /* This one's new.  You can provide functions to be called when the header info is valid,
    when each row is completed, and when the image is finished.  If you aren't using all functions,
    you can specify NULL parameters.  Even when all three functions are NULL, you need to call
    png_set_progressive_read_fn().  You can use any struct as the user_ptr (cast to a void pointer
    for the function call), and retrieve the pointer from inside the callbacks using the function

      png_get_progressive_ptr(png_ptr);

        which will return a void pointer, which you have
        to cast appropriately.
    */
  png_set_progressive_read_fn(png_ptr, (void *)this , info_callback, row_callback, end_callback);

  return 0;
}

/* A code fragment that you call as you receive blocks of data */
int nglImagePNGCodec::process_data(png_bytep buffer, png_uint_32 length)
{

  if (setjmp(png_jmpbuf( png_ptr )))
  {
    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    return -1;
  }

  /* This one's new also.  Simply give it a chunk
    of data from the file stream (in order, of
    course).  On machines with segmented memory
    models machines, don't give it any more than
    64K.  The library seems to run fine with sizes
    of 4K. Although you can give it much less if
    necessary (I assume you can give it chunks of
    1 byte, I haven't tried less then 256 bytes
    yet).  When this function returns, you may
    want to display any rows that were generated
    in the row callback if you don't already do
    so there.
    */
  png_process_data(png_ptr, info_ptr, buffer, length);
  return 0;
}

void nglImagePNGCodec::InfoCallback(png_structp png_ptr, png_infop info_ptr)
{
  nglImageInfo imginfo;

 short int color_type = png_get_color_type(png_ptr, info_ptr);

  // expand palette images to RGB, low-bit-depth grayscale images to 8 bits,
  // transparency chunks to full alpha channel; strip 16-bit-per-sample
  // images to 8 bits per sample; and convert grayscale to RGB[A]

  if (color_type == PNG_COLOR_TYPE_PALETTE)
      png_set_expand(png_ptr);
  if (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth( png_ptr, info_ptr ) < 8)
      png_set_expand(png_ptr);
  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
      png_set_expand(png_ptr);
//      if (GetBitDepth() == 16)
//          png_set_strip_16(mpPngData);
//  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
//      png_set_gray_to_rgb(png_ptr);

  if (png_get_interlace_type(png_ptr,info_ptr)!=PNG_INTERLACE_NONE)
    png_set_interlace_handling(png_ptr);

  png_read_update_info(png_ptr, info_ptr);

  imginfo.mWidth = png_get_image_width( png_ptr, info_ptr );
  imginfo.mHeight = png_get_image_height( png_ptr, info_ptr );
  imginfo.mBufferFormat = eImageFormatRaw;
  if (png_get_channels( png_ptr, info_ptr )==1)
    imginfo.mPixelFormat = eImagePixelLum;
  else if (png_get_channels( png_ptr, info_ptr )==2)
    imginfo.mPixelFormat = eImagePixelLumA;
  else if (png_get_channels( png_ptr, info_ptr )==3)
    imginfo.mPixelFormat = eImagePixelRGB;
  else if (png_get_channels( png_ptr, info_ptr )==4)
    imginfo.mPixelFormat = eImagePixelRGBA;

  imginfo.mBitDepth = png_get_bit_depth( png_ptr, info_ptr ) * png_get_channels( png_ptr, info_ptr );
  imginfo.mBytesPerPixel = imginfo.mBitDepth / 8;
  imginfo.mBytesPerLine = imginfo.mBytesPerPixel * imginfo.mWidth;

  SendInfo(imginfo);

  mpRowPointers = (png_byte**) malloc(imginfo.mHeight * sizeof(png_byte*));

  uint i;
  for(i = 0; i < imginfo.mHeight; i++)
    mpRowPointers[i] = (png_byte*)mpImage->GetBuffer()
                     + (imginfo.mHeight - i - 1) * imginfo.mBytesPerPixel * imginfo.mWidth;

  png_start_read_image(png_ptr);
}

bool nglImagePNGCodec::Feed(nglIStream* pIStream)
{
  nglFileSize size=pIStream->Available();
  char* buffer=new char[(size_t)size];
  pIStream->Read(buffer,(size_t)size,1);
  process_data((unsigned char*)buffer, (size_t)size);
  delete[] buffer;
  return true;
}

#ifdef _CARBON_
void nglWritePNG( png_structp png_ptr, png_bytep data, long unsigned int length )
#else
void nglWritePNG( png_structp png_ptr, png_bytep data, unsigned int length )
#endif
{
  ((nglOStream*)(png_get_io_ptr(png_ptr)))->Write( (png_byte *)data, (long int) length, 1 );
}

void nglFlushPNG( png_structp png_ptr )
{
}

bool nglImagePNGCodec::Save(nglOStream* pOStream)
{
  png_structp png_ptr = png_create_write_struct
                          ( PNG_LIBPNG_VER_STRING,
                            (png_voidp)NULL,
                            NULL,
                            NULL);
  if (!png_ptr)
    return false;

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr)
  {
    png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
    return false;
  }

  if (setjmp(png_ptr->jmpbuf))
  {
    png_destroy_write_struct(&png_ptr, &info_ptr);
    return false;
  }

  png_set_write_fn( png_ptr, (void*)pOStream, nglWritePNG, nglFlushPNG);

/* set the zlib compression level */
  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);

  /* set other zlib parameters */
  nglImageInfo Info;
  mpImage->GetInfo(Info);

  png_set_IHDR( png_ptr, info_ptr, Info.mWidth, Info.mHeight, Info.mBitDepth/Info.mBytesPerPixel,
                Info.mBytesPerPixel == 4 ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB,
                PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
              );

  uint i;
  png_byte **row_pointers;
  row_pointers = (png_byte**) malloc(Info.mHeight * sizeof(png_byte*));

  for(i = 0; i < Info.mHeight; i++)
    row_pointers[i] = (unsigned char*)(Info.mpBuffer + i * Info.mBytesPerLine);

  png_write_info(png_ptr, info_ptr);

  /* set up the transformations:  for now, just pack low-bit-depth pixels
  * into bytes (one, two or four pixels per byte) */

  png_set_packing(png_ptr);

  png_write_image (png_ptr, row_pointers);
  png_write_end(png_ptr, info_ptr); // Write the end chunck of the image.
  png_destroy_write_struct( &png_ptr, &info_ptr );
  free(row_pointers);
  return true;
}

float nglImagePNGCodec::GetCompletion()
{
  return 0;
}

#endif // HAVE_LIBPNG
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include <sal/config.h>
#include <stdio.h>
#include <sfx2/docfile.hxx>

#include "global.hxx"
#include "scerrors.hxx"
#include "docpool.hxx"
#include "patattr.hxx"
#include "filter.hxx"
#include "document.hxx"
#include "cell.hxx"
#include "biff.hxx"

ScBiffReader::ScBiffReader( SfxMedium & rMedium ) :
    mnId(0),
    mnLength(0),
    mnOffset(0)
{
    mpStream = rMedium.GetInStream();
    if( mpStream )
    {
        mpStream->SetBufferSize( 65535 );
        mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
    }
}

ScBiffReader::~ScBiffReader()
{
    if( mpStream )
        mpStream->SetBufferSize( 0 );
}

bool ScBiffReader::nextRecord()
{
    if( !recordsLeft() )
        return false;

    if( IsEndOfFile() )
        return false;

    sal_uInt32 nPos = mpStream->Tell();
    if( nPos != mnOffset + mnLength )
        mpStream->Seek( mnOffset + mnLength );

    mnLength = mnId = 0;
    *mpStream >> mnId >> mnLength;

    mnOffset = mpStream->Tell();
#ifdef DEBUG
    fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
        mnId, mnLength, mnOffset );

#if 1  // rather verbose
    int len = mnLength;
    while (len > 0) {
        int i, chunk = len < 16 ? len : 16;
        unsigned char data[16];
        mpStream->Read( data, chunk );

        for (i = 0; i < chunk; i++)
            fprintf( stderr, "%.2x ", data[i] );
        fprintf( stderr, "| " );
        for (i = 0; i < chunk; i++)
            fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
        fprintf( stderr, "\n" );

        len -= chunk;
    }
    mpStream->Seek( mnOffset );
#endif
#endif
    return true;
}

<commit_msg>INTEGRATION: CWS changefileheader (1.4.330); FILE MERGED 2008/03/31 17:14:50 rt 1.4.330.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: biff.cxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include <sal/config.h>
#include <stdio.h>
#include <sfx2/docfile.hxx>

#include "global.hxx"
#include "scerrors.hxx"
#include "docpool.hxx"
#include "patattr.hxx"
#include "filter.hxx"
#include "document.hxx"
#include "cell.hxx"
#include "biff.hxx"

ScBiffReader::ScBiffReader( SfxMedium & rMedium ) :
    mnId(0),
    mnLength(0),
    mnOffset(0)
{
    mpStream = rMedium.GetInStream();
    if( mpStream )
    {
        mpStream->SetBufferSize( 65535 );
        mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
    }
}

ScBiffReader::~ScBiffReader()
{
    if( mpStream )
        mpStream->SetBufferSize( 0 );
}

bool ScBiffReader::nextRecord()
{
    if( !recordsLeft() )
        return false;

    if( IsEndOfFile() )
        return false;

    sal_uInt32 nPos = mpStream->Tell();
    if( nPos != mnOffset + mnLength )
        mpStream->Seek( mnOffset + mnLength );

    mnLength = mnId = 0;
    *mpStream >> mnId >> mnLength;

    mnOffset = mpStream->Tell();
#ifdef DEBUG
    fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
        mnId, mnLength, mnOffset );

#if 1  // rather verbose
    int len = mnLength;
    while (len > 0) {
        int i, chunk = len < 16 ? len : 16;
        unsigned char data[16];
        mpStream->Read( data, chunk );

        for (i = 0; i < chunk; i++)
            fprintf( stderr, "%.2x ", data[i] );
        fprintf( stderr, "| " );
        for (i = 0; i < chunk; i++)
            fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
        fprintf( stderr, "\n" );

        len -= chunk;
    }
    mpStream->Seek( mnOffset );
#endif
#endif
    return true;
}

<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "perf_precomp.hpp"

using namespace std;
using namespace testing;
using namespace perf;

//////////////////////////////////////////////////////////////////////
// Blur

DEF_PARAM_TEST(Sz_Type_KernelSz, cv::Size, MatType, int);

PERF_TEST_P(Sz_Type_KernelSz, Blur,
            Combine(CUDA_TYPICAL_MAT_SIZES,
                    Values(CV_8UC1, CV_8UC4),
                    Values(3, 5, 7)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> blurFilter = cv::cuda::createBoxFilter(d_src.type(), -1, cv::Size(ksize, ksize));

        TEST_CYCLE() blurFilter->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst, 1);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::blur(src, dst, cv::Size(ksize, ksize));

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Filter2D

PERF_TEST_P(Sz_Type_KernelSz, Filter2D, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    cv::Mat kernel(ksize, ksize, CV_32FC1);
    declare.in(kernel, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> filter2D = cv::cuda::createLinearFilter(d_src.type(), -1, kernel);

        TEST_CYCLE() filter2D->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::filter2D(src, dst, -1, kernel);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Laplacian

PERF_TEST_P(Sz_Type_KernelSz, Laplacian, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(1, 3)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> laplacian = cv::cuda::createLaplacianFilter(d_src.type(), -1, ksize);

        TEST_CYCLE() laplacian->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Laplacian(src, dst, -1, ksize);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Sobel

PERF_TEST_P(Sz_Type_KernelSz, Sobel, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> sobel = cv::cuda::createSobelFilter(d_src.type(), -1, 1, 1, ksize);

        TEST_CYCLE() sobel->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Sobel(src, dst, -1, 1, 1, ksize);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Scharr

PERF_TEST_P(Sz_Type, Scharr, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> scharr = cv::cuda::createScharrFilter(d_src.type(), -1, 1, 0);

        TEST_CYCLE() scharr->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Scharr(src, dst, -1, 1, 0);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// GaussianBlur

PERF_TEST_P(Sz_Type_KernelSz, GaussianBlur, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> gauss = cv::cuda::createGaussianFilter(d_src.type(), -1, cv::Size(ksize, ksize), 0.5);

        TEST_CYCLE() gauss->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::GaussianBlur(src, dst, cv::Size(ksize, ksize), 0.5);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Erode

PERF_TEST_P(Sz_Type, Erode, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> erode = cv::cuda::createMorphologyFilter(cv::MORPH_ERODE, src.type(), ker);

        TEST_CYCLE() erode->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::erode(src, dst, ker);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Dilate

PERF_TEST_P(Sz_Type, Dilate, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> dilate = cv::cuda::createMorphologyFilter(cv::MORPH_DILATE, src.type(), ker);

        TEST_CYCLE() dilate->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::dilate(src, dst, ker);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// MorphologyEx

CV_ENUM(MorphOp, MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT)

DEF_PARAM_TEST(Sz_Type_Op, cv::Size, MatType, MorphOp);

PERF_TEST_P(Sz_Type_Op, MorphologyEx, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4), MorphOp::all()))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int morphOp = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> morph = cv::cuda::createMorphologyFilter(morphOp, src.type(), ker);

        TEST_CYCLE() morph->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::morphologyEx(src, dst, morphOp, ker);

        CPU_SANITY_CHECK(dst);
    }
}
//////////////////////////////////////////////////////////////////////
// MedianFilter
//////////////////////////////////////////////////////////////////////
// Median

DEF_PARAM_TEST(Sz_KernelSz, cv::Size, int);

//PERF_TEST_P(Sz_Type_KernelSz, Median, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1,CV_8UC1), Values(3, 5, 7, 9, 11, 13, 15)))
PERF_TEST_P(Sz_KernelSz, Median, Combine(CUDA_TYPICAL_MAT_SIZES, Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    // const int type = GET_PARAM(1);
    const int type = CV_8UC1;
    const int kernel = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> median = cv::cuda::createMedianFilter(d_src.type(), kernel);

        TEST_CYCLE() median->apply(d_src, dst);

        SANITY_CHECK_NOTHING();
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::medianBlur(src,dst,kernel);

        SANITY_CHECK_NOTHING();
    }
}<commit_msg>add performance test for CV_32FC1<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "perf_precomp.hpp"

using namespace std;
using namespace testing;
using namespace perf;

//////////////////////////////////////////////////////////////////////
// Blur

DEF_PARAM_TEST(Sz_Type_KernelSz, cv::Size, MatType, int);

PERF_TEST_P(Sz_Type_KernelSz, Blur,
            Combine(CUDA_TYPICAL_MAT_SIZES,
                    Values(CV_8UC1, CV_8UC4, CV_32FC1),
                    Values(3, 5, 7)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> blurFilter = cv::cuda::createBoxFilter(d_src.type(), -1, cv::Size(ksize, ksize));

        TEST_CYCLE() blurFilter->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst, 1);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::blur(src, dst, cv::Size(ksize, ksize));

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Filter2D

PERF_TEST_P(Sz_Type_KernelSz, Filter2D, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    cv::Mat kernel(ksize, ksize, CV_32FC1);
    declare.in(kernel, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> filter2D = cv::cuda::createLinearFilter(d_src.type(), -1, kernel);

        TEST_CYCLE() filter2D->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::filter2D(src, dst, -1, kernel);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Laplacian

PERF_TEST_P(Sz_Type_KernelSz, Laplacian, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1, CV_32FC4), Values(1, 3)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> laplacian = cv::cuda::createLaplacianFilter(d_src.type(), -1, ksize);

        TEST_CYCLE() laplacian->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Laplacian(src, dst, -1, ksize);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Sobel

PERF_TEST_P(Sz_Type_KernelSz, Sobel, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> sobel = cv::cuda::createSobelFilter(d_src.type(), -1, 1, 1, ksize);

        TEST_CYCLE() sobel->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Sobel(src, dst, -1, 1, 1, ksize);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Scharr

PERF_TEST_P(Sz_Type, Scharr, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> scharr = cv::cuda::createScharrFilter(d_src.type(), -1, 1, 0);

        TEST_CYCLE() scharr->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::Scharr(src, dst, -1, 1, 0);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// GaussianBlur

PERF_TEST_P(Sz_Type_KernelSz, GaussianBlur, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4, CV_32FC1), Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int ksize = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> gauss = cv::cuda::createGaussianFilter(d_src.type(), -1, cv::Size(ksize, ksize), 0.5);

        TEST_CYCLE() gauss->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::GaussianBlur(src, dst, cv::Size(ksize, ksize), 0.5);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Erode

PERF_TEST_P(Sz_Type, Erode, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> erode = cv::cuda::createMorphologyFilter(cv::MORPH_ERODE, src.type(), ker);

        TEST_CYCLE() erode->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::erode(src, dst, ker);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// Dilate

PERF_TEST_P(Sz_Type, Dilate, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> dilate = cv::cuda::createMorphologyFilter(cv::MORPH_DILATE, src.type(), ker);

        TEST_CYCLE() dilate->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::dilate(src, dst, ker);

        CPU_SANITY_CHECK(dst);
    }
}

//////////////////////////////////////////////////////////////////////
// MorphologyEx

CV_ENUM(MorphOp, MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT)

DEF_PARAM_TEST(Sz_Type_Op, cv::Size, MatType, MorphOp);

PERF_TEST_P(Sz_Type_Op, MorphologyEx, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1, CV_8UC4), MorphOp::all()))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    const int type = GET_PARAM(1);
    const int morphOp = GET_PARAM(2);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    const cv::Mat ker = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> morph = cv::cuda::createMorphologyFilter(morphOp, src.type(), ker);

        TEST_CYCLE() morph->apply(d_src, dst);

        CUDA_SANITY_CHECK(dst);
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::morphologyEx(src, dst, morphOp, ker);

        CPU_SANITY_CHECK(dst);
    }
}
//////////////////////////////////////////////////////////////////////
// MedianFilter
//////////////////////////////////////////////////////////////////////
// Median

DEF_PARAM_TEST(Sz_KernelSz, cv::Size, int);

//PERF_TEST_P(Sz_Type_KernelSz, Median, Combine(CUDA_TYPICAL_MAT_SIZES, Values(CV_8UC1,CV_8UC1), Values(3, 5, 7, 9, 11, 13, 15)))
PERF_TEST_P(Sz_KernelSz, Median, Combine(CUDA_TYPICAL_MAT_SIZES, Values(3, 5, 7, 9, 11, 13, 15)))
{
    declare.time(20.0);

    const cv::Size size = GET_PARAM(0);
    // const int type = GET_PARAM(1);
    const int type = CV_8UC1;
    const int kernel = GET_PARAM(1);

    cv::Mat src(size, type);
    declare.in(src, WARMUP_RNG);

    if (PERF_RUN_CUDA())
    {
        const cv::cuda::GpuMat d_src(src);
        cv::cuda::GpuMat dst;

        cv::Ptr<cv::cuda::Filter> median = cv::cuda::createMedianFilter(d_src.type(), kernel);

        TEST_CYCLE() median->apply(d_src, dst);

        SANITY_CHECK_NOTHING();
    }
    else
    {
        cv::Mat dst;

        TEST_CYCLE() cv::medianBlur(src,dst,kernel);

        SANITY_CHECK_NOTHING();
    }
}<|endoftext|>