#-------------------------------------------------------------
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
#-------------------------------------------------------------

/*
 * Simple utility to crop image of shape [N, 3 * Hin * Win] into [N, 3 * Hout * Wout]
 * Assumption: Hout < Hin, Wout < Win and input contains values [0, ..]
 */
crop_rgb = function(matrix[double] input, int Hin, int Win, int Hout, int Wout) return (matrix[double] out) {
	start_h = ceil((Hin - Hout) / 2)
	end_h = start_h + Hout - 1
	start_w = ceil((Win - Wout) / 2)
	end_w = start_w + Wout - 1
	mask = matrix(0, rows=Hin, cols=Win)
	temp_mask = matrix(1, rows=Hout, cols=Wout)
	mask[start_h:end_h, start_w:end_w] = temp_mask
	mask = matrix(mask, rows=1, cols=Hin*Win)
	mask = cbind(mask, mask, mask)
	out = removeEmpty(target=(input+1), margin="cols", select=mask) - 1
}

/*
 * Simple utility to crop image of shape [N, Hin * Win] into [N, Hout * Wout]
 * Assumption: Hout < Hin, Wout < Win and input contains values [0, ..]
 * 
 * Example PySpark script:
 * import matplotlib.pyplot as plt
 * from sklearn import datasets
 * digits = datasets.load_digits()
 * image = digits.images[3,].reshape(1, -1)
 * plt.imshow(image.reshape(8,8), cmap=plt.cm.gray_r)
 * plt.show()
 * 
 * script = """
 * crop_grayscale = function(matrix[double] input, int Hin, int Win, int Hout, int Wout) return (matrix[double] out) {
 * 	start_h = ceil((Hin - Hout) / 2)
 * 	end_h = start_h + Hout - 1
 * 	start_w = ceil((Win - Wout) / 2)
 * 	end_w = start_w + Wout - 1
 * 	mask = matrix(0, rows=Hin, cols=Win)
 * 	temp_mask = matrix(1, rows=Hout, cols=Wout)
 * 	mask[start_h:end_h, start_w:end_w] = temp_mask
 * 	mask = matrix(mask, rows=1, cols=Hin*Win)
 * 	out = removeEmpty(target=(input+1), margin="cols", select=mask) - 1
 * }
 * Y = crop_grayscale(X, 8, 8, 6, 6)
 * """
 * from systemds import MLContext, dml
 * ml = MLContext(sc)
 * script = dml(script).input(X=image).output("Y")
 * out = ml.execute(script).get("Y").toNumPy()
 * plt.imshow(out.reshape(6,6), cmap=plt.cm.gray_r)
 * plt.show()
 *
 */
crop_grayscale = function(matrix[double] input, int Hin, int Win, int Hout, int Wout) return (matrix[double] out) {
	start_h = ceil((Hin - Hout) / 2)
	end_h = start_h + Hout - 1
	start_w = ceil((Win - Wout) / 2)
	end_w = start_w + Wout - 1
	mask = matrix(0, rows=Hin, cols=Win)
	temp_mask = matrix(1, rows=Hout, cols=Wout)
	mask[start_h:end_h, start_w:end_w] = temp_mask
	mask = matrix(mask, rows=1, cols=Hin*Win)
	out = removeEmpty(target=(input+1), margin="cols", select=mask) - 1
}