Changing an Image's Size and Color Depth

When one "reduces the color depth" of an image to black and white, one examines each pixel, converts it to grayscale by averaging its red, green, and blue intensities, and then determines if it is closer to black or closer to white, "coloring it" appropriately.

When one reduces the size of an image, one breaks the pixels of the original image into blocks (i.e. groups) of pixels that will each be represented by a single pixel in the reduced image. The color for this single pixel comes from the averaged red, green, and blue intensities of pixels in the corresponding block.

The method below does both of these things to a selected image, returning an array representation of the new image, where 1 represents every place the image should be colored white, and 0 where it should be colored black. Modify the method below so that it both converts the image supplied into an array of $n$ shades of gray (uniformly chosen, and represented by integers $1$ through $n$), and enlarges the image in the case when numRows or numCols exceed the corresponding dimensions of the original picture.

public int[][] imageToArray(String imageFile, int numRows, int numCols, int threshold) {
	GImage originalImage_ = new GImage(imageFile);
	int[][] pixels = originalImage_.getPixelArray();
	int imageHeight = pixels.length;
	int imageWidth = pixels[0].length;
	int rowsPerBlock = imageHeight / numRows;
	int colsPerBlock = imageWidth / numCols;
	int[][] outputArray = new int[numRows][numCols];
	//for each block...
	for (int blockY = 0; blockY < numRows; blockY++) {
		for (int blockX = 0; blockX < numCols; blockX++) {
			//average the grayscale colors across the entire block
			long total = 0;
			for (int col = 0; col < colsPerBlock; col++) {
				for (int row = 0; row < rowsPerBlock; row++) {
					int r = blockY*rowsPerBlock + row;
					int c = blockX*colsPerBlock + col;
					int pixel = pixels[r][c];
					int red = GImage.getRed(pixel);
					int green = GImage.getGreen(pixel);
					int blue = GImage.getBlue(pixel);
					int gray = (red + green + blue) / 3;
					total += gray;
			long avg = total / (rowsPerBlock * colsPerBlock);
			if (avg > threshold) {
				outputArray[blockX][blockY] = 1;
			else {
				outputArray[blockX][blockY] = 2; 
	return outputArray;