#include <algorithm>
#include <cfloat>
#include <vector>
#include <iostream>

#include "caffe/common.hpp"
#include "caffe/layer.hpp"
#include "caffe/syncedmem.hpp"
#include "caffe/util/math_functions.hpp"
#include "caffe/vision_layers.hpp"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc.hpp>

namespace caffe {


template <typename Dtype>
void UpsamplingLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  LOG(INFO) << "********************";
  const Dtype* bottom_data = bottom[0]->gpu_data();
  //LOG(INFO) << bottom_data[0];
  LOG(INFO) << "bottom_data:" <<bottom_data;
  LOG(INFO) << "1111111111111111111111";
  Dtype* top_data = (*top)[0]->mutable_gpu_data();
  LOG(INFO) << "top_data:" << top_data;
  const int top_count = (*top)[0]->count();
  cv::Mat low_img(height_, width_, CV_8UC1);
int M=(bottom[0]->count())/(bottom[0]->num());
LOG(INFO) << "M=" << M << ", channels=" << channels_ << ", height=" << height_ << ", width=" << width_;
int Mtop=((*top)[0]->count())/((*top)[0]->num());
LOG(INFO) << "Mtop=" << Mtop << ", channels=" << channels_ << ", size_h_=" << size_h_ << ", size_w_=" << size_w_;
int offset2;
  for (int i = 0; i < bottom[0]->num(); i++){
	  offset2 = 0;
  for (int c = 0; c < 1; ++c) {
  	for (int h = 0; h < low_img.rows; ++h) {
  		for (int w = 0; w < low_img.cols; ++w) {
  		LOG(INFO) << "(" << h << "," << w << ")";
  			low_img.at<uchar>(h, w) = bottom_data[i*M+offset2];
  			offset2++;
  		}
  	}
  }
  LOG(INFO) << "rows:" << low_img.rows << ", cols:" << low_img.cols;
  LOG(INFO) << "resizing";
  cv::Mat resize_img(size_h_, size_w_, CV_8UC1);
  cv::resize(low_img, resize_img, cv::Size(size_h_, size_w_));
  cv::imshow("gt_test", resize_img);
  cv::waitKey(1000);
  offset2 = 0;
  for (int c = 0; c < 1; ++c) {
    	for (int h = 0; h < resize_img.rows; ++h) {
    		for (int w = 0; w < resize_img.cols; ++w) {
    			top_data[i*Mtop+offset2] = resize_img.at<uchar>(h, w);
    			offset2++;
    		}
    	}
    }
  }
  LOG(INFO) << "upsampling forward end";
}





template <typename Dtype>
void UpsamplingLayer<Dtype>::Backward_gpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {
  return;
  CUDA_POST_KERNEL_CHECK;
}


INSTANTIATE_CLASS(UpsamplingLayer);


}  // namespace caffe